Home | History | Annotate | Download | only in dom
      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:
     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 
     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:
     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 
     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 
     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
    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