diff options
author | yzshen@chromium.org <yzshen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-05 07:10:58 +0000 |
---|---|---|
committer | yzshen@chromium.org <yzshen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-05 07:10:58 +0000 |
commit | 7ac673b55f9c2334d531c280f907e2d0edaed68b (patch) | |
tree | 1dbb373bcfb3cd61836fe17a3f1807f7aaf36ec5 /ppapi/utility | |
parent | 88f11549025ad46da215d208a016387619d7271d (diff) | |
download | chromium_src-7ac673b55f9c2334d531c280f907e2d0edaed68b.zip chromium_src-7ac673b55f9c2334d531c280f907e2d0edaed68b.tar.gz chromium_src-7ac673b55f9c2334d531c280f907e2d0edaed68b.tar.bz2 |
Change the cpp wrappers of audio input/video capture to use CompletionCallbackWithOutput.
And also fix a few bugs in the PP_ArrayOutput and CallbackWithOutput code.
- Make sure POD members of Dispatcher\.* are properly initialized.
- Avoid leaking var/resource references in DispatcherWithOutput\.*::operator().
BUG=None
TEST=None
Review URL: http://codereview.chromium.org/9965080
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@130849 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/utility')
-rw-r--r-- | ppapi/utility/completion_callback_factory.h | 108 |
1 files changed, 86 insertions, 22 deletions
diff --git a/ppapi/utility/completion_callback_factory.h b/ppapi/utility/completion_callback_factory.h index e7e7c86..d521f4b 100644 --- a/ppapi/utility/completion_callback_factory.h +++ b/ppapi/utility/completion_callback_factory.h @@ -570,8 +570,12 @@ 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); + + // Please note that |object| may be NULL at this point. But we still need + // to call into Dispatcher::operator() in that case, so that it can do + // necessary cleanup. + (*self->dispatcher_)(object, result); + delete self; } @@ -592,7 +596,8 @@ class CompletionCallbackFactory { explicit Dispatcher0(Method method) : method_(method) { } void operator()(T* object, int32_t result) { - (object->*method_)(result); + if (object) + (object->*method_)(result); } private: Method method_; @@ -604,11 +609,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 +637,17 @@ class CompletionCallbackFactory { template <typename Method, typename A> class Dispatcher1 { public: - Dispatcher1() : method_(NULL) {} + Dispatcher1() + : method_(NULL), + a_() { + } 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 +660,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 +691,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 +717,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 +751,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 +764,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 +781,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_; |