Chromium Code Reviews| Index: ppapi/utility/completion_callback_factory.h |
| diff --git a/ppapi/utility/completion_callback_factory.h b/ppapi/utility/completion_callback_factory.h |
| index e7e7c863c9dbb1e0fd0f30199672dac8e2f3364d..42ebbf35033fe00e5e11be8a6378e93f4c962a27 100644 |
| --- a/ppapi/utility/completion_callback_factory.h |
| +++ b/ppapi/utility/completion_callback_factory.h |
| @@ -570,8 +570,7 @@ class CompletionCallbackFactory { |
| static void Thunk(void* user_data, int32_t result) { |
| Self* self = static_cast<Self*>(user_data); |
| T* object = self->back_pointer_->GetObject(); |
| - if (object) |
| - (*self->dispatcher_)(object, result); |
| + (*self->dispatcher_)(object, result); |
| delete self; |
| } |
| @@ -592,7 +591,8 @@ class CompletionCallbackFactory { |
| explicit Dispatcher0(Method method) : method_(method) { |
| } |
| void operator()(T* object, int32_t result) { |
| - (object->*method_)(result); |
| + if (object) |
|
brettw
2012/04/03 21:23:03
I don't totally get this change, can you clarify w
yzshen1
2012/04/04 00:36:34
Because I change Thunk() to call Dispatcher*::oper
|
| + (object->*method_)(result); |
| } |
| private: |
| Method method_; |
| @@ -604,11 +604,21 @@ class CompletionCallbackFactory { |
| typedef Output OutputType; |
| typedef internal::CallbackOutputTraits<Output> Traits; |
| - DispatcherWithOutput0() : method_(NULL) {} |
| - DispatcherWithOutput0(Method method) : method_(method) { |
| + DispatcherWithOutput0() |
| + : method_(NULL), |
| + output_() { |
| + } |
| + DispatcherWithOutput0(Method method) |
| + : method_(method), |
| + output_() { |
| } |
| void operator()(T* object, int32_t result) { |
| - (object->*method_)(result, Traits::StorageToPluginArg(output_)); |
| + // We must call Traits::StorageToPluginArg() even if we don't need to call |
| + // the callback anymore, otherwise we may leak resource or var references. |
| + if (object) |
| + (object->*method_)(result, Traits::StorageToPluginArg(output_)); |
| + else |
| + Traits::StorageToPluginArg(output_); |
| } |
| typename Traits::StorageType* output() { |
| return &output_; |
| @@ -622,13 +632,17 @@ class CompletionCallbackFactory { |
| template <typename Method, typename A> |
| class Dispatcher1 { |
| public: |
| - Dispatcher1() : method_(NULL) {} |
| + Dispatcher1() |
| + : method_(NULL), |
| + a_() { |
|
brettw
2012/04/03 21:23:03
Do you initialize these arguments just for complet
yzshen1
2012/04/04 00:36:34
Yes. I understand that.
If we want to init |metho
|
| + } |
| Dispatcher1(Method method, const A& a) |
| : method_(method), |
| a_(a) { |
| } |
| void operator()(T* object, int32_t result) { |
| - (object->*method_)(result, a_); |
| + if (object) |
| + (object->*method_)(result, a_); |
| } |
| private: |
| Method method_; |
| @@ -641,13 +655,23 @@ class CompletionCallbackFactory { |
| typedef Output OutputType; |
| typedef internal::CallbackOutputTraits<Output> Traits; |
| - DispatcherWithOutput1() : method_(NULL) {} |
| + DispatcherWithOutput1() |
| + : method_(NULL), |
| + a_(), |
| + output_() { |
| + } |
| DispatcherWithOutput1(Method method, const A& a) |
| : method_(method), |
| - a_(a) { |
| + a_(a), |
| + output_() { |
| } |
| void operator()(T* object, int32_t result) { |
| - (object->*method_)(result, Traits::StorageToPluginArg(output_), a_); |
| + // We must call Traits::StorageToPluginArg() even if we don't need to call |
| + // the callback anymore, otherwise we may leak resource or var references. |
| + if (object) |
| + (object->*method_)(result, Traits::StorageToPluginArg(output_), a_); |
| + else |
| + Traits::StorageToPluginArg(output_); |
| } |
| typename Traits::StorageType* output() { |
| return &output_; |
| @@ -662,14 +686,19 @@ class CompletionCallbackFactory { |
| template <typename Method, typename A, typename B> |
| class Dispatcher2 { |
| public: |
| - Dispatcher2() : method_(NULL) {} |
| + Dispatcher2() |
| + : method_(NULL), |
| + a_(), |
| + b_() { |
| + } |
| Dispatcher2(Method method, const A& a, const B& b) |
| : method_(method), |
| a_(a), |
| b_(b) { |
| } |
| void operator()(T* object, int32_t result) { |
| - (object->*method_)(result, a_, b_); |
| + if (object) |
| + (object->*method_)(result, a_, b_); |
| } |
| private: |
| Method method_; |
| @@ -683,14 +712,25 @@ class CompletionCallbackFactory { |
| typedef Output OutputType; |
| typedef internal::CallbackOutputTraits<Output> Traits; |
| - DispatcherWithOutput2() : method_(NULL) {} |
| + DispatcherWithOutput2() |
| + : method_(NULL), |
| + a_(), |
| + b_(), |
| + output_() { |
| + } |
| DispatcherWithOutput2(Method method, const A& a, const B& b) |
| : method_(method), |
| a_(a), |
| - b_(b) { |
| + b_(b), |
| + output_() { |
| } |
| void operator()(T* object, int32_t result) { |
| - (object->*method_)(result, Traits::StorageToPluginArg(output_), a_, b_); |
| + // We must call Traits::StorageToPluginArg() even if we don't need to call |
| + // the callback anymore, otherwise we may leak resource or var references. |
| + if (object) |
| + (object->*method_)(result, Traits::StorageToPluginArg(output_), a_, b_); |
| + else |
| + Traits::StorageToPluginArg(output_); |
| } |
| typename Traits::StorageType* output() { |
| return &output_; |
| @@ -706,7 +746,12 @@ class CompletionCallbackFactory { |
| template <typename Method, typename A, typename B, typename C> |
| class Dispatcher3 { |
| public: |
| - Dispatcher3() : method_(NULL) {} |
| + Dispatcher3() |
| + : method_(NULL), |
| + a_(), |
| + b_(), |
| + c_() { |
| + } |
| Dispatcher3(Method method, const A& a, const B& b, const C& c) |
| : method_(method), |
| a_(a), |
| @@ -714,7 +759,8 @@ class CompletionCallbackFactory { |
| c_(c) { |
| } |
| void operator()(T* object, int32_t result) { |
| - (object->*method_)(result, a_, b_, c_); |
| + if (object) |
| + (object->*method_)(result, a_, b_, c_); |
| } |
| private: |
| Method method_; |
| @@ -730,16 +776,29 @@ class CompletionCallbackFactory { |
| typedef Output OutputType; |
| typedef internal::CallbackOutputTraits<Output> Traits; |
| - DispatcherWithOutput3() : method_(NULL) {} |
| + DispatcherWithOutput3() |
| + : method_(NULL), |
| + a_(), |
| + b_(), |
| + c_(), |
| + output_() { |
| + } |
| DispatcherWithOutput3(Method method, const A& a, const B& b, const C& c) |
| : method_(method), |
| a_(a), |
| b_(b), |
| - c_(c) { |
| + c_(c), |
| + output_() { |
| } |
| void operator()(T* object, int32_t result) { |
| - (object->*method_)(result, Traits::StorageToPluginArg(output_), |
| - a_, b_, c_); |
| + // We must call Traits::StorageToPluginArg() even if we don't need to call |
| + // the callback anymore, otherwise we may leak resource or var references. |
| + if (object) { |
| + (object->*method_)(result, Traits::StorageToPluginArg(output_), |
| + a_, b_, c_); |
| + } else { |
| + Traits::StorageToPluginArg(output_); |
| + } |
| } |
| typename Traits::StorageType* output() { |
| return &output_; |