Index: base/observer_list_threadsafe.h |
diff --git a/base/observer_list_threadsafe.h b/base/observer_list_threadsafe.h |
index 5174667e603157656feabe4d7cc94eab80421902..49dc859f8f9d1dd72533f81a899e6c24cf50e7de 100644 |
--- a/base/observer_list_threadsafe.h |
+++ b/base/observer_list_threadsafe.h |
@@ -61,21 +61,15 @@ class ObserverListThreadSafe; |
namespace internal { |
-// An UnboundMethod is a wrapper for a method where the actual object is |
-// provided at Run dispatch time. |
-template <class T, class Method, class Params> |
-class UnboundMethod { |
- public: |
- UnboundMethod(Method m, const Params& p) : m_(m), p_(p) { |
- static_assert((internal::ParamsUseScopedRefptrCorrectly<Params>::value), |
- "bad unbound method params"); |
dcheng
2016/08/24 21:18:27
If I understand correctly, the reason this is safe
tzik
2016/08/25 00:53:01
Yes, it's done in Bind().
|
- } |
- void Run(T* obj) const { |
- DispatchToMethod(obj, m_, p_); |
+template <typename ObserverType, typename Method> |
+struct Dispatcher; |
+ |
+template <typename ObserverType, typename ReceiverType, typename... Params> |
+struct Dispatcher<ObserverType, void(ReceiverType::*)(Params...)> { |
+ static void Run(void(ReceiverType::* m)(Params...), |
+ Params... params, ObserverType* obj) { |
+ (obj->*m)(std::forward<Params>(params)...); |
} |
- private: |
- Method m_; |
- Params p_; |
}; |
} // namespace internal |
@@ -173,20 +167,19 @@ class ObserverListThreadSafe |
// Note, these calls are effectively asynchronous. You cannot assume |
// that at the completion of the Notify call that all Observers have |
// been Notified. The notification may still be pending delivery. |
- template <class Method, class... Params> |
+ template <typename Method, typename... Params> |
void Notify(const tracked_objects::Location& from_here, |
- Method m, |
- const Params&... params) { |
- internal::UnboundMethod<ObserverType, Method, std::tuple<Params...>> method( |
- m, std::make_tuple(params...)); |
+ Method m, Params&&... params) { |
+ Callback<void(ObserverType*)> method = |
+ Bind(&internal::Dispatcher<ObserverType, Method>::Run, |
+ m, std::forward<Params>(params)...); |
AutoLock lock(list_lock_); |
for (const auto& entry : observer_lists_) { |
ObserverListContext* context = entry.second; |
context->task_runner->PostTask( |
from_here, |
- Bind(&ObserverListThreadSafe<ObserverType>::template NotifyWrapper< |
- Method, std::tuple<Params...>>, |
+ Bind(&ObserverListThreadSafe<ObserverType>::NotifyWrapper, |
this, context, method)); |
} |
} |
@@ -213,10 +206,8 @@ class ObserverListThreadSafe |
// Wrapper which is called to fire the notifications for each thread's |
// ObserverList. This function MUST be called on the thread which owns |
// the unsafe ObserverList. |
- template <class Method, class Params> |
- void NotifyWrapper( |
- ObserverListContext* context, |
- const internal::UnboundMethod<ObserverType, Method, Params>& method) { |
+ void NotifyWrapper(ObserverListContext* context, |
+ const Callback<void(ObserverType*)>& method) { |
// Check that this list still needs notifications. |
{ |
AutoLock lock(list_lock_); |