Make ContentDecryptionModuleResult cross-thread destructible.

So as to handle cross-thread uses of the corresponding
WebContentDecryptionModuleResult (WCDMResult), have WCDMResult
keep a cross-thread persistent (CrossThreadPersistent<>) by
way of its WebPrivatePtr<> reference.

CrossThreadPersistent<> can be destructed on a thread other than
the Oilpan thread creating it; the thread does not have to be
attached to Oilpan.

To control if WebPrivatePtr<> should use a cross-thread persistent
or not, it is now parameterized over an enum controlling which.
The default is to use same-thread persistents. If

  WebPrivatePtr<T, AllowCrossThreadDestruction>

is for a ref-counted T, T must derive from ThreadSafeRefCounted<T>. 

R=jrummell,xhwang,haraken,tkent
BUG=509588

Review URL: https://codereview.chromium.org/1249913002

git-svn-id: svn://svn.chromium.org/blink/trunk@199421 bbb929c8-8fbe-4397-9dbb-9b2b20218538
diff --git a/third_party/WebKit/public/platform/WebContentDecryptionModuleResult.h b/third_party/WebKit/public/platform/WebContentDecryptionModuleResult.h
index f06bbec..9d16de99 100644
--- a/third_party/WebKit/public/platform/WebContentDecryptionModuleResult.h
+++ b/third_party/WebKit/public/platform/WebContentDecryptionModuleResult.h
@@ -66,7 +66,7 @@
     BLINK_PLATFORM_EXPORT void reset();
     BLINK_PLATFORM_EXPORT void assign(const WebContentDecryptionModuleResult&);
 
-    WebPrivatePtr<ContentDecryptionModuleResult> m_impl;
+    WebPrivatePtr<ContentDecryptionModuleResult, WebPrivatePtrDestructionCrossThread> m_impl;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/public/platform/WebPrivatePtr.h b/third_party/WebKit/public/platform/WebPrivatePtr.h
index f62961f..b4b9a28 100644
--- a/third_party/WebKit/public/platform/WebPrivatePtr.h
+++ b/third_party/WebKit/public/platform/WebPrivatePtr.h
@@ -39,8 +39,20 @@
 #include "wtf/TypeTraits.h"
 #endif
 
+namespace WTF {
+template<class T> class ThreadSafeRefCounted;
+}
+
 namespace blink {
 
+// By default, the destruction of a WebPrivatePtr<> must happen on the same
+// thread that created it, but can optionally be allowed to happen on
+// another thread.
+enum WebPrivatePtrDestruction {
+    WebPrivatePtrDestructionSameThread,
+    WebPrivatePtrDestructionCrossThread,
+};
+
 #if INSIDE_BLINK
 enum LifetimeManagementType {
     RefCountedLifetime,
@@ -58,16 +70,17 @@
         isRefCountedGarbageCollected ? RefCountedGarbageCollectedLifetime : GarbageCollectedLifetime;
 };
 
-template<typename T, LifetimeManagementType lifetime>
+template<typename T, WebPrivatePtrDestruction crossThreadDestruction, LifetimeManagementType lifetime>
 class PtrStorageImpl;
 
-template<typename T>
-class PtrStorageImpl<T, RefCountedLifetime> {
+template<typename T, WebPrivatePtrDestruction crossThreadDestruction>
+class PtrStorageImpl<T, crossThreadDestruction, RefCountedLifetime> {
 public:
     typedef PassRefPtr<T> BlinkPtrType;
 
     void assign(const BlinkPtrType& val)
     {
+        static_assert(crossThreadDestruction == WebPrivatePtrDestructionSameThread || WTF::IsSubclassOfTemplate<T, WTF::ThreadSafeRefCounted>::value, "Cross thread destructible class must derive from ThreadSafeRefCounted<>");
         release();
         m_ptr = val.leakRef();
     }
@@ -99,8 +112,20 @@
     T* m_ptr;
 };
 
-template<typename T>
-class PtrStorageImpl<T, GarbageCollectedLifetime> {
+template <typename T, WebPrivatePtrDestruction>
+struct WebPrivatePtrPersistentStorageType {
+public:
+    using Type = Persistent<T>;
+};
+
+template <typename T>
+struct WebPrivatePtrPersistentStorageType<T, WebPrivatePtrDestructionCrossThread> {
+public:
+    using Type = CrossThreadPersistent<T>;
+};
+
+template<typename T, WebPrivatePtrDestruction crossThreadDestruction>
+class PtrStorageImpl<T, crossThreadDestruction, GarbageCollectedLifetime> {
 public:
     void assign(const RawPtr<T>& val)
     {
@@ -110,7 +135,7 @@
         }
 
         if (!m_handle)
-            m_handle = new Persistent<T>();
+            m_handle = new (typename WebPrivatePtrPersistentStorageType<T, crossThreadDestruction>::Type)();
 
         (*m_handle) = val;
     }
@@ -136,19 +161,19 @@
     }
 
 private:
-    Persistent<T>* m_handle;
+    typename WebPrivatePtrPersistentStorageType<T, crossThreadDestruction>::Type* m_handle;
 };
 
-template<typename T>
-class PtrStorageImpl<T, RefCountedGarbageCollectedLifetime> : public PtrStorageImpl<T, GarbageCollectedLifetime> {
+template<typename T, WebPrivatePtrDestruction crossThreadDestruction>
+class PtrStorageImpl<T, crossThreadDestruction, RefCountedGarbageCollectedLifetime> : public PtrStorageImpl<T, crossThreadDestruction, GarbageCollectedLifetime> {
 public:
-    void assign(const PassRefPtrWillBeRawPtr<T>& val) { PtrStorageImpl<T, GarbageCollectedLifetime>::assign(val.get()); }
+    void assign(const PassRefPtrWillBeRawPtr<T>& val) { PtrStorageImpl<T, crossThreadDestruction, GarbageCollectedLifetime>::assign(val.get()); }
 
-    void assign(const PtrStorageImpl& other) { PtrStorageImpl<T, GarbageCollectedLifetime>::assign(other.get()); }
+    void assign(const PtrStorageImpl& other) { PtrStorageImpl<T, crossThreadDestruction, GarbageCollectedLifetime>::assign(other.get()); }
 };
 
-template<typename T>
-class PtrStorage : public PtrStorageImpl<T, LifetimeOf<T>::value> {
+template<typename T, WebPrivatePtrDestruction crossThreadDestruction>
+class PtrStorage : public PtrStorageImpl<T, crossThreadDestruction, LifetimeOf<T>::value> {
 public:
     static PtrStorage& fromSlot(void** slot)
     {
@@ -169,7 +194,6 @@
 };
 #endif
 
-
 // This class is an implementation detail of the Blink API. It exists to help
 // simplify the implementation of Blink interfaces that merely wrap a reference
 // counted WebCore class.
@@ -206,7 +230,7 @@
 //    WebFoo::~WebFoo() { m_private.reset(); }
 //    void WebFoo::assign(const WebFoo& other) { ... }
 //
-template <typename T>
+template <typename T, WebPrivatePtrDestruction crossThreadDestruction = WebPrivatePtrDestructionSameThread>
 class WebPrivatePtr {
 public:
     WebPrivatePtr() : m_storage(0) { }
@@ -231,20 +255,20 @@
 
     void reset() { storage().release(); }
 
-    WebPrivatePtr<T>& operator=(const WebPrivatePtr<T>& other)
+    WebPrivatePtr& operator=(const WebPrivatePtr& other)
     {
         storage().assign(other.storage());
         return *this;
     }
 
-    void moveFrom(WebPrivatePtr<T>& other)
+    void moveFrom(WebPrivatePtr& other)
     {
         storage().moveFrom(other.storage());
         return;
     }
 
     template<typename U>
-    WebPrivatePtr<T>& operator=(const U& ptr)
+    WebPrivatePtr& operator=(const U& ptr)
     {
         storage().assign(ptr);
         return *this;
@@ -267,8 +291,8 @@
 
 private:
 #if INSIDE_BLINK
-    PtrStorage<T>& storage() { return PtrStorage<T>::fromSlot(&m_storage); }
-    const PtrStorage<T>& storage() const { return PtrStorage<T>::fromSlot(&m_storage); }
+    PtrStorage<T, crossThreadDestruction>& storage() { return PtrStorage<T, crossThreadDestruction>::fromSlot(&m_storage); }
+    const PtrStorage<T, crossThreadDestruction>& storage() const { return PtrStorage<T, crossThreadDestruction>::fromSlot(&m_storage); }
 #endif
 
 #if !INSIDE_BLINK
@@ -276,11 +300,11 @@
     // INSIDE_BLINK is set, but we need to make sure that it is not
     // used outside there; the compiler-provided version won't handle reference
     // counting properly.
-    WebPrivatePtr<T>& operator=(const WebPrivatePtr<T>& other);
+    WebPrivatePtr& operator=(const WebPrivatePtr& other);
 #endif
     // Disable the copy constructor; classes that contain a WebPrivatePtr
     // should implement their copy constructor using assign().
-    WebPrivatePtr(const WebPrivatePtr<T>&);
+    WebPrivatePtr(const WebPrivatePtr&);
 
     void* m_storage;
 };