15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version. 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful, 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details. 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB. If not, write to 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA. 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef RefCounted_h 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define RefCounted_h 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 24197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "wtf/Assertions.h" 2593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "wtf/FastAllocBase.h" 26a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "wtf/InstanceCounter.h" 2793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "wtf/Noncopyable.h" 2893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "wtf/WTFExport.h" 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 30197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT) 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define CHECK_REF_COUNTED_LIFECYCLE 1 32c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "wtf/ThreadRestrictionVerifier.h" 33197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#else 34197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#define CHECK_REF_COUNTED_LIFECYCLE 0 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 37c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)namespace WTF { 38c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// This base class holds the non-template methods and attributes. 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// The RefCounted class inherits from it reducing the template bloat 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// generated by the compiler (technique called template hoisting). 4293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)class WTF_EXPORT RefCountedBase { 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void ref() 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if CHECK_REF_COUNTED_LIFECYCLE 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Start thread verification as soon as the ref count gets to 2. This 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // heuristic reflects the fact that items are often created on one thread 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // and then given to another thread to be used. 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: Make this restriction tigher. Especially as we move to more 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // common methods for sharing items across threads like CrossThreadCopier.h 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We should be able to add a "detachFromThread" method to make this explicit. 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_refCount == 1) 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_verifier.setShared(true); 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If this assert fires, it either indicates a thread safety issue or 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // that the verification needs to change. See ThreadRestrictionVerifier for 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // the different modes. 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_verifier.isSafeToUse()); 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!m_adoptionIsRequired); 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 611e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) ASSERT_WITH_SECURITY_IMPLICATION(!m_deletionHasBegun); 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++m_refCount; 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool hasOneRef() const 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) ASSERT_WITH_SECURITY_IMPLICATION(!m_deletionHasBegun); 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if CHECK_REF_COUNTED_LIFECYCLE 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_verifier.isSafeToUse()); 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_refCount == 1; 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int refCount() const 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if CHECK_REF_COUNTED_LIFECYCLE 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_verifier.isSafeToUse()); 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_refCount; 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)protected: 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefCountedBase() 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_refCount(1) 85197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(SECURITY_ASSERT) 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_deletionHasBegun(false) 871e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#endif 881e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#if CHECK_REF_COUNTED_LIFECYCLE 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_adoptionIsRequired(true) 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ~RefCountedBase() 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 961e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) ASSERT_WITH_SECURITY_IMPLICATION(m_deletionHasBegun); 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if CHECK_REF_COUNTED_LIFECYCLE 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!m_adoptionIsRequired); 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Returns whether the pointer should be freed or not. 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool derefBase() 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1051e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) ASSERT_WITH_SECURITY_IMPLICATION(!m_deletionHasBegun); 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if CHECK_REF_COUNTED_LIFECYCLE 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_verifier.isSafeToUse()); 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!m_adoptionIsRequired); 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_refCount > 0); 11207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch --m_refCount; 11307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!m_refCount) { 114197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(SECURITY_ASSERT) 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_deletionHasBegun = true; 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if CHECK_REF_COUNTED_LIFECYCLE 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Stop thread verification when the ref goes to 1 because it 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // is safe to be passed to another thread at this point. 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_refCount == 1) 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_verifier.setShared(false); 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if CHECK_REF_COUNTED_LIFECYCLE 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool deletionHasBegun() const 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_deletionHasBegun; 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private: 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 138197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if CHECK_REF_COUNTED_LIFECYCLE || ENABLE(SECURITY_ASSERT) 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) friend void adopted(RefCountedBase*); 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int m_refCount; 143197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(SECURITY_ASSERT) 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool m_deletionHasBegun; 1451e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#endif 1461e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#if CHECK_REF_COUNTED_LIFECYCLE 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool m_adoptionIsRequired; 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ThreadRestrictionVerifier m_verifier; 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 152197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if CHECK_REF_COUNTED_LIFECYCLE || ENABLE(SECURITY_ASSERT) 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline void adopted(RefCountedBase* object) 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!object) 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) ASSERT_WITH_SECURITY_IMPLICATION(!object->m_deletionHasBegun); 1581e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#if CHECK_REF_COUNTED_LIFECYCLE 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) object->m_adoptionIsRequired = false; 1601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#endif 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template<typename T> class RefCounted : public RefCountedBase { 165c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) WTF_MAKE_NONCOPYABLE(RefCounted); 166c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) WTF_MAKE_FAST_ALLOCATED; 167a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void deref() 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (derefBase()) 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) delete static_cast<T*>(this); 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)protected: 176a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#ifdef ENABLE_INSTANCE_COUNTER 177a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) RefCounted() 178a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) { 179a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) incrementInstanceCount<T>(static_cast<T*>(this)); 180a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 181a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ~RefCounted() 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 184a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) decrementInstanceCount<T>(static_cast<T*>(this)); 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 186a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#else 187a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) RefCounted() 188a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) { 189a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 190a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#endif 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WTF 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using WTF::RefCounted; 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif // RefCounted_h 198