• 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 "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