1 /*
2 * Copyright (C) 2006, 2007, 2009, 2010, 2012 Apple Inc. All rights reserved.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 *
19 */
20
21 #ifndef TreeShared_h
22 #define TreeShared_h
23
24 #include "wtf/Assertions.h"
25 #include "wtf/MainThread.h"
26 #include "wtf/Noncopyable.h"
27
28 namespace WebCore {
29
30 #if SECURITY_ASSERT_ENABLED
31 template<typename NodeType> class TreeShared;
32 template<typename NodeType> void adopted(TreeShared<NodeType>*);
33 #endif
34
35 template<typename NodeType> class TreeShared {
36 WTF_MAKE_NONCOPYABLE(TreeShared);
37 protected:
TreeShared()38 TreeShared()
39 : m_refCount(1)
40 #if SECURITY_ASSERT_ENABLED
41 , m_deletionHasBegun(false)
42 #if !ASSERT_DISABLED
43 , m_inRemovedLastRefFunction(false)
44 , m_adoptionIsRequired(true)
45 #endif
46 #endif
47 {
48 ASSERT(isMainThread());
49 }
50
~TreeShared()51 ~TreeShared()
52 {
53 ASSERT(isMainThread());
54 ASSERT(!m_refCount);
55 ASSERT_WITH_SECURITY_IMPLICATION(m_deletionHasBegun);
56 ASSERT(!m_adoptionIsRequired);
57 }
58
59 public:
ref()60 void ref()
61 {
62 ASSERT(isMainThread());
63 ASSERT_WITH_SECURITY_IMPLICATION(!m_deletionHasBegun);
64 ASSERT(!m_inRemovedLastRefFunction);
65 ASSERT(!m_adoptionIsRequired);
66 ++m_refCount;
67 }
68
deref()69 void deref()
70 {
71 ASSERT(isMainThread());
72 ASSERT(m_refCount >= 0);
73 ASSERT_WITH_SECURITY_IMPLICATION(!m_deletionHasBegun);
74 ASSERT(!m_inRemovedLastRefFunction);
75 ASSERT(!m_adoptionIsRequired);
76 NodeType* thisNode = static_cast<NodeType*>(this);
77 if (--m_refCount <= 0 && !thisNode->hasTreeSharedParent()) {
78 #if !ASSERT_DISABLED
79 m_inRemovedLastRefFunction = true;
80 #endif
81 thisNode->removedLastRef();
82 }
83 }
84
refCount()85 int refCount() const
86 {
87 return m_refCount;
88 }
89
90 private:
91 int m_refCount;
92
93 #if SECURITY_ASSERT_ENABLED
94 public:
95 bool m_deletionHasBegun;
96 #if !ASSERT_DISABLED
97 bool m_inRemovedLastRefFunction;
98
99 private:
100 friend void adopted<>(TreeShared<NodeType>*);
101 bool m_adoptionIsRequired;
102 #endif
103 #endif
104 };
105
106 #if SECURITY_ASSERT_ENABLED
adopted(TreeShared<NodeType> * object)107 template<typename NodeType> inline void adopted(TreeShared<NodeType>* object)
108 {
109 if (!object)
110 return;
111 ASSERT_WITH_SECURITY_IMPLICATION(!object->m_deletionHasBegun);
112 #if !ASSERT_DISABLED
113 ASSERT(!object->m_inRemovedLastRefFunction);
114 object->m_adoptionIsRequired = false;
115 #endif
116 }
117 #endif
118
119 }
120
121 #endif // TreeShared.h
122