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 "public/platform/WebPrivatePtr.h"
25 #include "wtf/Assertions.h"
26 #include "wtf/MainThread.h"
27 #include "wtf/Noncopyable.h"
28
29 namespace blink {
30
31 #if ENABLE(SECURITY_ASSERT)
32 template<typename NodeType> class TreeShared;
33 template<typename NodeType> void adopted(TreeShared<NodeType>*);
34 #endif
35
36 template<typename NodeType> class TreeShared : public NoBaseWillBeGarbageCollectedFinalized<NodeType> {
37 WTF_MAKE_NONCOPYABLE(TreeShared);
38 protected:
TreeShared()39 TreeShared()
40 : m_refCount(1)
41 #if ENABLE(SECURITY_ASSERT)
42 , m_deletionHasBegun(false)
43 #if ENABLE(ASSERT)
44 , m_inRemovedLastRefFunction(false)
45 , m_adoptionIsRequired(true)
46 #endif
47 #endif
48 {
49 ASSERT(isMainThread());
50 }
51
~TreeShared()52 ~TreeShared()
53 {
54 ASSERT(isMainThread());
55 ASSERT(!m_refCount);
56 ASSERT_WITH_SECURITY_IMPLICATION(m_deletionHasBegun);
57 ASSERT(!m_adoptionIsRequired);
58 }
59
60 public:
ref()61 void ref()
62 {
63 ASSERT(isMainThread());
64 ASSERT_WITH_SECURITY_IMPLICATION(!m_deletionHasBegun);
65 ASSERT(!m_inRemovedLastRefFunction);
66 ASSERT(!m_adoptionIsRequired);
67 ++m_refCount;
68 }
69
deref()70 void deref()
71 {
72 ASSERT(isMainThread());
73 ASSERT(m_refCount > 0);
74 ASSERT_WITH_SECURITY_IMPLICATION(!m_deletionHasBegun);
75 ASSERT(!m_inRemovedLastRefFunction);
76 ASSERT(!m_adoptionIsRequired);
77 NodeType* thisNode = static_cast<NodeType*>(this);
78 if (!--m_refCount && !thisNode->hasTreeSharedParent()) {
79 #if ENABLE(ASSERT)
80 m_inRemovedLastRefFunction = true;
81 #endif
82 thisNode->removedLastRef();
83 }
84 }
85
refCount()86 int refCount() const { return m_refCount; }
87
88 private:
89 int m_refCount;
90
91 #if ENABLE(SECURITY_ASSERT)
92 public:
93 bool m_deletionHasBegun;
94 #if ENABLE(ASSERT)
95 bool m_inRemovedLastRefFunction;
96
97 private:
98 friend void adopted<>(TreeShared<NodeType>*);
99 bool m_adoptionIsRequired;
100 #endif
101 #endif
102 };
103
104 #if ENABLE(SECURITY_ASSERT)
adopted(TreeShared<NodeType> * object)105 template<typename NodeType> void adopted(TreeShared<NodeType>* object)
106 {
107 if (!object)
108 return;
109
110 ASSERT_WITH_SECURITY_IMPLICATION(!object->m_deletionHasBegun);
111 #if ENABLE(ASSERT)
112 ASSERT(!object->m_inRemovedLastRefFunction);
113 object->m_adoptionIsRequired = false;
114 #endif
115 }
116 #endif
117
118 }
119
120 #endif // TreeShared.h
121