• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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