Chromium Code Reviews| Index: Source/platform/heap/Heap.h |
| diff --git a/Source/platform/heap/Heap.h b/Source/platform/heap/Heap.h |
| index 7023c7143159d87ffd067f84b4f4d85738aecbb3..617afbba1fcbdbfb38e04f855ab82ca1d979635f 100644 |
| --- a/Source/platform/heap/Heap.h |
| +++ b/Source/platform/heap/Heap.h |
| @@ -40,6 +40,7 @@ |
| #include "wtf/LinkedHashSet.h" |
| #include "wtf/OwnPtr.h" |
| #include "wtf/PassRefPtr.h" |
| +#include "wtf/ThreadSafeRefCounted.h" |
| #include <stdint.h> |
| @@ -68,6 +69,7 @@ class HeapStats; |
| class PageMemory; |
| template<ThreadAffinity affinity> class ThreadLocalPersistents; |
| template<typename T, typename RootsAccessor = ThreadLocalPersistents<ThreadingTrait<T>::Affinity > > class Persistent; |
| +template<typename T> class CrossThreadPersistent; |
| PLATFORM_EXPORT size_t osPageSize(); |
| @@ -540,6 +542,63 @@ private: |
| friend class ThreadState; |
| }; |
| +// FIXME: This is currently used by the WebAudio code. |
| +// We should attempt to restructure the WebAudio code so that the main thread |
| +// alone determines life-time and receives messages about life-time from the |
| +// audio thread. |
| +template<typename T> |
| +class ThreadSafeRefCountedGarbageCollected : public GarbageCollectedFinalized<T>, public WTF::ThreadSafeRefCountedBase { |
| + WTF_MAKE_NONCOPYABLE(ThreadSafeRefCountedGarbageCollected); |
| + |
| +public: |
| + ThreadSafeRefCountedGarbageCollected() |
| + { |
| +#ifndef NDEBUG |
| + m_threadState = ThreadState::current(); |
|
Mads Ager (chromium)
2014/04/24 09:05:37
In the code on the branch I used this threadState
keishi
2014/05/06 20:00:03
Done.
|
| +#endif |
| + m_keepAlive = adoptPtr(new CrossThreadPersistent<T>(static_cast<T*>(this))); |
| + } |
| + |
| + // Override ref to deal with a case where a reference count goes up |
| + // from 0 to 1. This can happen in the following scenario: |
| + // (1) The reference count becomes 0, but on-stack pointers keep references to the object. |
| + // (2) The on-stack pointer is assigned to a RefPtr. The reference count becomes 1. |
| + // In this case, we have to resurrect m_keepAlive. |
| + void ref() |
| + { |
| + MutexLocker lock(m_mutex); |
| + if (UNLIKELY(!refCount())) { |
| + ASSERT(!m_keepAlive); |
| + ASSERT(m_threadState->contains(reinterpret_cast<Address>(this))); |
| + m_keepAlive = adoptPtr(new CrossThreadPersistent<T>(static_cast<T*>(this))); |
| + } |
| + WTF::ThreadSafeRefCountedBase::ref(); |
| + } |
| + |
| + // Override deref to deal with our own deallocation based on ref counting. |
| + void deref() |
| + { |
| + MutexLocker lock(m_mutex); |
| + if (derefBase()) { |
| + ASSERT(m_keepAlive); |
| + m_keepAlive.clear(); |
| + } |
| + } |
| + |
| + using GarbageCollectedFinalized<T>::operator new; |
| + using GarbageCollectedFinalized<T>::operator delete; |
| + |
| +protected: |
| + ~ThreadSafeRefCountedGarbageCollected() { } |
| + |
| +private: |
| + OwnPtr<CrossThreadPersistent<T> > m_keepAlive; |
| + mutable Mutex m_mutex; |
| +#ifndef NDEBUG |
| + ThreadState* m_threadState; |
| +#endif |
| +}; |
| + |
| // The CallbackStack contains all the visitor callbacks used to trace and mark |
| // objects. A specific CallbackStack instance contains at most bufferSize elements. |
| // If more space is needed a new CallbackStack instance is created and chained |