Title: [140040] trunk/Source/WTF
Revision
140040
Author
aba...@webkit.org
Date
2013-01-17 14:17:12 -0800 (Thu, 17 Jan 2013)

Log Message

Teach Functional.h about WeakPtr
https://bugs.webkit.org/show_bug.cgi?id=107105

Reviewed by Anders Carlsson.

A common pattern in cross-thread communication is to call member
functions of an object on a remote thread. If the caller's reference to
the object on the remote thread is a WeakPtr, the caller usually wants
to validate that the object still exists when the call actually takes
place.

It's possible to do this manually for every cross-thread call, but that
is tiresome and error prone. Instead, we can teach bind to validate
WeakPtr arguments when passed as the "this" parameter to a member
function.

* wtf/Functional.h:
(WTF::ParamStorageTraits::validate):

Modified Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (140039 => 140040)


--- trunk/Source/WTF/ChangeLog	2013-01-17 22:06:13 UTC (rev 140039)
+++ trunk/Source/WTF/ChangeLog	2013-01-17 22:17:12 UTC (rev 140040)
@@ -1,3 +1,24 @@
+2013-01-17  Adam Barth  <aba...@webkit.org>
+
+        Teach Functional.h about WeakPtr
+        https://bugs.webkit.org/show_bug.cgi?id=107105
+
+        Reviewed by Anders Carlsson.
+
+        A common pattern in cross-thread communication is to call member
+        functions of an object on a remote thread. If the caller's reference to
+        the object on the remote thread is a WeakPtr, the caller usually wants
+        to validate that the object still exists when the call actually takes
+        place.
+
+        It's possible to do this manually for every cross-thread call, but that
+        is tiresome and error prone. Instead, we can teach bind to validate
+        WeakPtr arguments when passed as the "this" parameter to a member
+        function.
+
+        * wtf/Functional.h:
+        (WTF::ParamStorageTraits::validate):
+
 2013-01-17  David Kilzer  <ddkil...@apple.com>
 
         Fix vprintf_stderr_common() to compile with -Wshorten-64-to-32

Modified: trunk/Source/WTF/wtf/Functional.h (140039 => 140040)


--- trunk/Source/WTF/wtf/Functional.h	2013-01-17 22:06:13 UTC (rev 140039)
+++ trunk/Source/WTF/wtf/Functional.h	2013-01-17 22:17:12 UTC (rev 140040)
@@ -30,6 +30,7 @@
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefPtr.h>
 #include <wtf/ThreadSafeRefCounted.h>
+#include <wtf/WeakPtr.h>
 
 #if PLATFORM(MAC) && COMPILER_SUPPORTS(BLOCKS)
 #include <Block.h>
@@ -82,6 +83,7 @@
 public:
     typedef R ResultType;
     static const bool shouldRefFirstParameter = false;
+    static const bool shouldValidateFirstParameter = false;
 
     explicit FunctionWrapper(R (*function)())
         : m_function(function)
@@ -102,6 +104,7 @@
 public:
     typedef R ResultType;
     static const bool shouldRefFirstParameter = false;
+    static const bool shouldValidateFirstParameter = false;
 
     explicit FunctionWrapper(R (*function)(P1))
         : m_function(function)
@@ -122,6 +125,7 @@
 public:
     typedef R ResultType;
     static const bool shouldRefFirstParameter = false;
+    static const bool shouldValidateFirstParameter = false;
 
     explicit FunctionWrapper(R (*function)(P1, P2))
         : m_function(function)
@@ -142,6 +146,7 @@
 public:
     typedef R ResultType;
     static const bool shouldRefFirstParameter = false;
+    static const bool shouldValidateFirstParameter = false;
 
     explicit FunctionWrapper(R (*function)(P1, P2, P3))
         : m_function(function)
@@ -162,6 +167,7 @@
 public:
     typedef R ResultType;
     static const bool shouldRefFirstParameter = HasRefAndDeref<C>::value;
+    static const bool shouldValidateFirstParameter = true;
 
     explicit FunctionWrapper(R (C::*function)())
         : m_function(function)
@@ -182,6 +188,7 @@
 public:
     typedef R ResultType;
     static const bool shouldRefFirstParameter = HasRefAndDeref<C>::value;
+    static const bool shouldValidateFirstParameter = true;
 
     explicit FunctionWrapper(R (C::*function)(P1))
         : m_function(function)
@@ -202,6 +209,7 @@
 public:
     typedef R ResultType;
     static const bool shouldRefFirstParameter = HasRefAndDeref<C>::value;
+    static const bool shouldValidateFirstParameter = true;
 
     explicit FunctionWrapper(R (C::*function)(P1, P2))
         : m_function(function)
@@ -222,6 +230,7 @@
 public:
     typedef R ResultType;
     static const bool shouldRefFirstParameter = HasRefAndDeref<C>::value;
+    static const bool shouldValidateFirstParameter = true;
 
     explicit FunctionWrapper(R (C::*function)(P1, P2, P3))
         : m_function(function)
@@ -242,6 +251,7 @@
 public:
     typedef R ResultType;
     static const bool shouldRefFirstParameter = HasRefAndDeref<C>::value;
+    static const bool shouldValidateFirstParameter = true;
 
     explicit FunctionWrapper(R (C::*function)(P1, P2, P3, P4))
         : m_function(function)
@@ -262,6 +272,7 @@
 public:
     typedef R ResultType;
     static const bool shouldRefFirstParameter = HasRefAndDeref<C>::value;
+    static const bool shouldValidateFirstParameter = true;
 
     explicit FunctionWrapper(R (C::*function)(P1, P2, P3, P4, P5))
         : m_function(function)
@@ -283,6 +294,7 @@
 public:
     typedef R ResultType;
     static const bool shouldRefFirstParameter = false;
+    static const bool shouldValidateFirstParameter = false;
 
     explicit FunctionWrapper(R (^block)())
         : m_block(Block_copy(block))
@@ -323,6 +335,7 @@
     typedef T StorageType;
 
     static StorageType wrap(const T& value) { return value; }
+    static bool validate(const StorageType&) { return true; }
     static const T& unwrap(const StorageType& value) { return value; }
 };
 
@@ -330,6 +343,7 @@
     typedef RefPtr<T> StorageType;
 
     static StorageType wrap(PassRefPtr<T> value) { return value; }
+    static bool validate(const StorageType&) { return true; }
     static T* unwrap(const StorageType& value) { return value.get(); }
 };
 
@@ -337,16 +351,26 @@
     typedef RefPtr<T> StorageType;
 
     static StorageType wrap(RefPtr<T> value) { return value.release(); }
+    static bool validate(const StorageType&) { return true; }
     static T* unwrap(const StorageType& value) { return value.get(); }
 };
 
+template<typename T> struct ParamStorageTraits<WeakPtr<T> > {
+    typedef WeakPtr<T> StorageType;
 
+    static StorageType wrap(WeakPtr<T> value) { return value; }
+    static bool validate(const StorageType& value) { return value.get(); }
+    static T* unwrap(const StorageType& value) { return value.get(); }
+};
+
+
 template<typename> class RetainPtr;
 
 template<typename T> struct ParamStorageTraits<RetainPtr<T> > {
     typedef RetainPtr<T> StorageType;
 
     static StorageType wrap(const RetainPtr<T>& value) { return value; }
+    static bool validate(const StorageType&) { return true; }
     static typename RetainPtr<T>::PtrType unwrap(const StorageType& value) { return value.get(); }
 };
 
@@ -375,7 +399,7 @@
     {
     }
 
-    virtual R operator()()
+    virtual typename FunctionWrapper::ResultType operator()()
     {
         return m_functionWrapper();
     }
@@ -386,7 +410,6 @@
 
 template<typename FunctionWrapper, typename R, typename P1>
 class BoundFunctionImpl<FunctionWrapper, R (P1)> : public FunctionImpl<typename FunctionWrapper::ResultType ()> {
-
 public:
     BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1)
         : m_functionWrapper(functionWrapper)
@@ -400,8 +423,10 @@
         RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::deref(m_p1);
     }
 
-    virtual R operator()()
+    virtual typename FunctionWrapper::ResultType operator()()
     {
+        if (FunctionWrapper::shouldValidateFirstParameter && !ParamStorageTraits<P1>::validate(m_p1))
+            return typename FunctionWrapper::ResultType();
         return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1));
     }
 
@@ -428,6 +453,8 @@
 
     virtual typename FunctionWrapper::ResultType operator()()
     {
+        if (FunctionWrapper::shouldValidateFirstParameter && !ParamStorageTraits<P1>::validate(m_p1))
+            return typename FunctionWrapper::ResultType();
         return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStorageTraits<P2>::unwrap(m_p2));
     }
 
@@ -456,6 +483,8 @@
 
     virtual typename FunctionWrapper::ResultType operator()()
     {
+        if (FunctionWrapper::shouldValidateFirstParameter && !ParamStorageTraits<P1>::validate(m_p1))
+            return typename FunctionWrapper::ResultType();
         return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStorageTraits<P2>::unwrap(m_p2), ParamStorageTraits<P3>::unwrap(m_p3));
     }
 
@@ -486,6 +515,8 @@
 
     virtual typename FunctionWrapper::ResultType operator()()
     {
+        if (FunctionWrapper::shouldValidateFirstParameter && !ParamStorageTraits<P1>::validate(m_p1))
+            return typename FunctionWrapper::ResultType();
         return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStorageTraits<P2>::unwrap(m_p2), ParamStorageTraits<P3>::unwrap(m_p3), ParamStorageTraits<P4>::unwrap(m_p4));
     }
 
@@ -518,6 +549,8 @@
 
     virtual typename FunctionWrapper::ResultType operator()()
     {
+        if (FunctionWrapper::shouldValidateFirstParameter && !ParamStorageTraits<P1>::validate(m_p1))
+            return typename FunctionWrapper::ResultType();
         return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStorageTraits<P2>::unwrap(m_p2), ParamStorageTraits<P3>::unwrap(m_p3), ParamStorageTraits<P4>::unwrap(m_p4), ParamStorageTraits<P5>::unwrap(m_p5));
     }
 
@@ -552,6 +585,8 @@
 
     virtual typename FunctionWrapper::ResultType operator()()
     {
+        if (FunctionWrapper::shouldValidateFirstParameter && !ParamStorageTraits<P1>::validate(m_p1))
+            return typename FunctionWrapper::ResultType();
         return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStorageTraits<P2>::unwrap(m_p2), ParamStorageTraits<P3>::unwrap(m_p3), ParamStorageTraits<P4>::unwrap(m_p4), ParamStorageTraits<P5>::unwrap(m_p5), ParamStorageTraits<P6>::unwrap(m_p6));
     }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to