Index: Source/platform/scheduler/CancellableTaskFactory.h |
diff --git a/Source/platform/scheduler/CancellableTaskFactory.h b/Source/platform/scheduler/CancellableTaskFactory.h |
index 2d1a642b309cc1e1a4842006e67dd875e3612195..932963a6d452b8496c09f94c4e29110396474339 100644 |
--- a/Source/platform/scheduler/CancellableTaskFactory.h |
+++ b/Source/platform/scheduler/CancellableTaskFactory.h |
@@ -6,27 +6,51 @@ |
#define CancellableTaskFactory_h |
#include "platform/PlatformExport.h" |
+#include "platform/heap/Handle.h" |
#include "public/platform/WebScheduler.h" |
-#include "wtf/AddressSanitizer.h" |
#include "wtf/Functional.h" |
#include "wtf/Noncopyable.h" |
#include "wtf/OwnPtr.h" |
#include "wtf/PassOwnPtr.h" |
#include "wtf/RefCounted.h" |
+#include "wtf/TypeTraits.h" |
#include "wtf/WeakPtr.h" |
namespace blink { |
+ |
class TraceLocation; |
class PLATFORM_EXPORT CancellableTaskFactory { |
WTF_MAKE_NONCOPYABLE(CancellableTaskFactory); |
- |
+ WTF_MAKE_FAST_ALLOCATED(CancellableTaskFactory); |
public: |
+ // A pair of mutually exclusive factory methods are provided for constructing |
+ // a CancellableTaskFactory, one for when a Oilpan heap object owns a |
+ // CancellableTaskFactory, and one when that owning object isn't controlled |
+ // by Oilpan. |
+ // |
+ // In the Oilpan case, as WTF::Closure objects are off-heap, we have to construct the |
+ // closure in such a manner that it doesn't end up referring back to the owning heap |
+ // object with a strong Persistent<> GC root reference. If we do, this will create |
+ // a heap <-> off-heap cycle and leak, the owning object can never be GCed. |
+ // Instead, the closure will keep an off-heap persistent reference of the weak |
+ // variety, which will refer back to the owner heap object safely (but weakly.) |
+ // |
+ template<typename T> |
+ static PassOwnPtr<CancellableTaskFactory> create(T* thisObject, void (T::*method)(), typename WTF::EnableIf<IsGarbageCollectedType<T>::value>::Type* = nullptr) |
+ { |
+ return adoptPtr(new CancellableTaskFactory(WTF::bind(method, AllowCrossThreadWeakPersistent<T>(thisObject)))); |
+ } |
+ |
+ template<typename T> |
+ static PassOwnPtr<CancellableTaskFactory> create(T* thisObject, void (T::*method)(), typename WTF::EnableIf<!IsGarbageCollectedType<T>::value>::Type* = nullptr) |
+ { |
+ return adoptPtr(new CancellableTaskFactory(WTF::bind(method, thisObject))); |
+ } |
+ |
+ // Only intended used by unit tests. Please use leak safe create() factory method, if possible. |
explicit CancellableTaskFactory(PassOwnPtr<Closure> closure) |
: m_closure(closure) |
-#if defined(ADDRESS_SANITIZER) |
- , m_unpoisonBeforeUpdate(false) |
-#endif |
, m_weakPtrFactory(this) |
{ |
} |
@@ -42,15 +66,6 @@ public: |
// ownership of the task. Creating a new task cancels any previous ones. |
WebTaskRunner::Task* cancelAndCreate(); |
-#if defined(ADDRESS_SANITIZER) |
- // The CancellableTaskFactory part object might be within a poisoned heap |
- // object, hence CancellableTask::run() will access poisoned memory |
- // when reaching into the factory object to update its state. |
- // We will allow such access iff the task factory is marked as requiring |
- // unpoisoning first. |
- void setUnpoisonBeforeUpdate() { m_unpoisonBeforeUpdate = true; } |
-#endif |
- |
private: |
class CancellableTask : public WebTaskRunner::Task { |
WTF_MAKE_NONCOPYABLE(CancellableTask); |
@@ -68,9 +83,6 @@ private: |
}; |
OwnPtr<Closure> m_closure; |
-#if defined(ADDRESS_SANITIZER) |
- bool m_unpoisonBeforeUpdate; |
-#endif |
WeakPtrFactory<CancellableTaskFactory> m_weakPtrFactory; |
}; |