Home | History | Annotate | Download | only in utility
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef PPAPI_UTILITY_COMPLETION_CALLBACK_FACTORY_H_
      6 #define PPAPI_UTILITY_COMPLETION_CALLBACK_FACTORY_H_
      7 
      8 #include "ppapi/cpp/completion_callback.h"
      9 #include "ppapi/utility/completion_callback_factory_thread_traits.h"
     10 
     11 /// @file
     12 /// This file defines the API to create CompletionCallback objects that are
     13 /// bound to member functions.
     14 namespace pp {
     15 
     16 // TypeUnwrapper --------------------------------------------------------------
     17 
     18 namespace internal {
     19 
     20 // The TypeUnwrapper converts references and const references to the
     21 // underlying type used for storage and passing as an argument. It is for
     22 // internal use only.
     23 template <typename T> struct TypeUnwrapper {
     24   typedef T StorageType;
     25 };
     26 template <typename T> struct TypeUnwrapper<T&> {
     27   typedef T StorageType;
     28 };
     29 template <typename T> struct TypeUnwrapper<const T&> {
     30   typedef T StorageType;
     31 };
     32 
     33 }  // namespace internal
     34 
     35 // ----------------------------------------------------------------------------
     36 
     37 /// CompletionCallbackFactory<T> may be used to create CompletionCallback
     38 /// objects that are bound to member functions.
     39 ///
     40 /// If a factory is destroyed, then any pending callbacks will be cancelled
     41 /// preventing any bound member functions from being called.  The CancelAll()
     42 /// method allows pending callbacks to be cancelled without destroying the
     43 /// factory.
     44 ///
     45 /// <strong>Note: </strong><code>CompletionCallbackFactory<T></code> isn't
     46 /// thread safe, but it is somewhat thread-friendly when used with a
     47 /// thread-safe traits class as the second template element. However, it
     48 /// only guarantees safety for creating a callback from another thread, the
     49 /// callback itself needs to execute on the same thread as the thread that
     50 /// creates/destroys the factory. With this restriction, it is safe to create
     51 /// the <code>CompletionCallbackFactory</code> on the main thread, create
     52 /// callbacks from any thread and pass them to CallOnMainThread().
     53 ///
     54 /// <strong>Example: </strong>
     55 ///
     56 /// @code
     57 ///   class MyClass {
     58 ///    public:
     59 ///     // If an compiler warns on following using |this| in the initializer
     60 ///     // list, use PP_ALLOW_THIS_IN_INITIALIZER_LIST macro.
     61 ///     MyClass() : factory_(this) {
     62 ///     }
     63 ///
     64 ///     void OpenFile(const pp::FileRef& file) {
     65 ///       pp::CompletionCallback cc = factory_.NewCallback(&MyClass::DidOpen);
     66 ///       int32_t rv = file_io_.Open(file, PP_FileOpenFlag_Read, cc);
     67 ///       CHECK(rv == PP_OK_COMPLETIONPENDING);
     68 ///     }
     69 ///
     70 ///    private:
     71 ///     void DidOpen(int32_t result) {
     72 ///       if (result == PP_OK) {
     73 ///         // The file is open, and we can begin reading.
     74 ///         // ...
     75 ///       } else {
     76 ///         // Failed to open the file with error given by 'result'.
     77 ///       }
     78 ///     }
     79 ///
     80 ///     pp::CompletionCallbackFactory<MyClass> factory_;
     81 ///   };
     82 /// @endcode
     83 ///
     84 /// <strong>Passing additional parameters to your callback</strong>
     85 ///
     86 /// As a convenience, the <code>CompletionCallbackFactory</code> can optionally
     87 /// create a closure with up to three bound parameters that it will pass to
     88 /// your callback function. This can be useful for passing information about
     89 /// the request to your callback function, which is especially useful if your
     90 /// class has multiple asynchronous callbacks pending.
     91 ///
     92 /// For the above example, of opening a file, let's say you want to keep some
     93 /// description associated with your request, you might implement your OpenFile
     94 /// and DidOpen callback as follows:
     95 ///
     96 /// @code
     97 ///   void OpenFile(const pp::FileRef& file) {
     98 ///     std::string message = "Opening file!";
     99 ///     pp::CompletionCallback cc = factory_.NewCallback(&MyClass::DidOpen,
    100 ///                                                      message);
    101 ///     int32_t rv = file_io_.Open(file, PP_FileOpenFlag_Read, cc);
    102 ///     CHECK(rv == PP_OK_COMPLETIONPENDING);
    103 ///   }
    104 ///   void DidOpen(int32_t result, const std::string& message) {
    105 ///     // "message" will be "Opening file!".
    106 ///     ...
    107 ///   }
    108 /// @endcode
    109 ///
    110 /// <strong>Optional versus required callbacks</strong>
    111 ///
    112 /// When you create an "optional" callback, the browser may return the results
    113 /// synchronously if they are available. This can allow for higher performance
    114 /// in some cases if data is available quickly (for example, for network loads
    115 /// where there may be a lot of data coming quickly). In this case, the
    116 /// callback will never be run.
    117 ///
    118 /// When creating a new callback with the factory, there will be data allocated
    119 /// on the heap that tracks the callback information and any bound arguments.
    120 /// This data is freed when the callback executes. In the case of optional
    121 /// callbacks, since the browser will never issue the callback, the internal
    122 /// tracking data will be leaked.
    123 ///
    124 /// Therefore, if you use optional callbacks, it's important to manually
    125 /// issue the callback to free up this data. The typical pattern is:
    126 ///
    127 /// @code
    128 ///   pp::CompletionCallback callback = callback_factory.NewOptionalCallback(
    129 ///       &MyClass::OnDataReady);
    130 ///   int32_t result = interface->GetData(callback);
    131 ///   if (result != PP_OK_COMPLETIONPENDING)
    132 ///      callback.Run(result);
    133 /// @endcode
    134 ///
    135 /// Because of this additional complexity, it's generally recommended that
    136 /// you not use optional callbacks except when performance is more important
    137 /// (such as loading large resources from the network). In most other cases,
    138 /// the performance difference will not be worth the additional complexity,
    139 /// and most functions may never actually have the ability to complete
    140 /// synchronously.
    141 ///
    142 /// <strong>Completion callbacks with output</strong>
    143 ///
    144 /// For some API calls, the browser returns data to the caller via an output
    145 /// parameter. These can be difficult to manage since the output parameter
    146 /// must remain valid for as long as the callback is pending. Note also that
    147 /// CancelAll (or destroying the callback factory) does <i>not</i> cancel the
    148 /// callback from the browser's perspective, only the execution of the callback
    149 /// in the plugin code, and the output parameter will still be written to!
    150 /// This means that you can't use class members as output parameters without
    151 /// risking crashes.
    152 ///
    153 /// To make this case easier, the CompletionCallbackFactory can allocate and
    154 /// manage the output data for you and pass it to your callback function. This
    155 /// makes such calls more natural and less error-prone.
    156 ///
    157 /// To create such a callback, use NewCallbackWithOutput and specify a callback
    158 /// function that takes the output parameter as its second argument. Let's say
    159 /// you're calling a function GetFile which asynchronously returns a
    160 /// pp::FileRef. GetFile's signature will be <code>int32_t GetFile(const
    161 /// CompletionCallbackWithOutput<pp::FileRef>& callback);</code> and your
    162 /// calling code would look like this:
    163 ///
    164 /// @code
    165 ///   void RequestFile() {
    166 ///     file_interface->GetFile(callback_factory_.NewCallbackWithOutput(
    167 ///         &MyClass::GotFile));
    168 ///   }
    169 ///   void GotFile(int32_t result, const pp::FileRef& file) {
    170 ///     if (result == PP_OK) {
    171 ///       ...use file...
    172 ///     } else {
    173 ///       ...handle error...
    174 ///     }
    175 ///   }
    176 /// @endcode
    177 ///
    178 /// As with regular completion callbacks, you can optionally add up to three
    179 /// bound arguments. These are passed following the output argument.
    180 ///
    181 /// Your callback may take the output argument as a copy (common for small
    182 /// types like integers, a const reference (common for structures and
    183 /// resources to avoid an extra copy), or as a non-const reference. One
    184 /// optimization you can do if your callback function may take large arrays
    185 /// is to accept your output argument as a non-const reference and to swap()
    186 /// the argument with a vector of your own to store it. This means you don't
    187 /// have to copy the buffer to consume it.
    188 template <typename T, typename ThreadTraits = ThreadSafeThreadTraits>
    189 class CompletionCallbackFactory {
    190  public:
    191 
    192   /// This constructor creates a <code>CompletionCallbackFactory</code>
    193   /// bound to an object. If the constructor is called without an argument,
    194   /// the default value of <code>NULL</code> is used. The user then must call
    195   /// Initialize() to initialize the object.
    196   ///
    197   /// param[in] object Optional parameter. An object whose member functions
    198   /// are to be bound to CompletionCallbacks created by this
    199   /// <code>CompletionCallbackFactory</code>. The default value of this
    200   /// parameter is <code>NULL</code>.
    201   explicit CompletionCallbackFactory(T* object = NULL)
    202       : object_(object) {
    203     // Assume that we don't need to lock since construction should be complete
    204     // before the pointer is used on another thread.
    205     InitBackPointer();
    206   }
    207 
    208   /// Destructor.
    209   ~CompletionCallbackFactory() {
    210     // Assume that we don't need to lock since this object should not be used
    211     // from multiple threads during destruction.
    212     ResetBackPointer();
    213   }
    214 
    215   /// CancelAll() cancels all <code>CompletionCallbacks</code> allocated from
    216   /// this factory.
    217   void CancelAll() {
    218     typename ThreadTraits::AutoLock lock(lock_);
    219 
    220     ResetBackPointer();
    221     InitBackPointer();
    222   }
    223 
    224   /// Initialize() binds the <code>CallbackFactory</code> to a particular
    225   /// object. Use this when the object is not available at
    226   /// <code>CallbackFactory</code> creation, and the <code>NULL</code> default
    227   /// is passed to the constructor. The object may only be initialized once,
    228   /// either by the constructor, or by a call to Initialize().
    229   ///
    230   /// This class may not be used on any thread until initialization is complete.
    231   ///
    232   /// @param[in] object The object whose member functions are to be bound to
    233   /// the <code>CompletionCallback</code> created by this
    234   /// <code>CompletionCallbackFactory</code>.
    235   void Initialize(T* object) {
    236     PP_DCHECK(object);
    237     PP_DCHECK(!object_);  // May only initialize once!
    238     object_ = object;
    239   }
    240 
    241   /// GetObject() returns the object that was passed at initialization to
    242   /// Intialize().
    243   ///
    244   /// @return the object passed to the constructor or Intialize().
    245   T* GetObject() {
    246     return object_;
    247   }
    248 
    249   /// NewCallback allocates a new, single-use <code>CompletionCallback</code>.
    250   /// The <code>CompletionCallback</code> must be run in order for the memory
    251   /// allocated by the methods to be freed.
    252   ///
    253   /// @param[in] method The method to be invoked upon completion of the
    254   /// operation.
    255   ///
    256   /// @return A <code>CompletionCallback</code>.
    257   template <typename Method>
    258   CompletionCallback NewCallback(Method method) {
    259     return NewCallbackHelper(new Dispatcher0<Method>(method));
    260   }
    261 
    262   /// NewOptionalCallback() allocates a new, single-use
    263   /// <code>CompletionCallback</code> that might not run if the method
    264   /// taking it can complete synchronously. Thus, if after passing the
    265   /// CompletionCallback to a Pepper method, the method does not return
    266   /// PP_OK_COMPLETIONPENDING, then you should manually call the
    267   /// CompletionCallback's Run method, or memory will be leaked.
    268   ///
    269   /// @param[in] method The method to be invoked upon completion of the
    270   /// operation.
    271   ///
    272   /// @return A <code>CompletionCallback</code>.
    273   template <typename Method>
    274   CompletionCallback NewOptionalCallback(Method method) {
    275     CompletionCallback cc = NewCallback(method);
    276     cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL);
    277     return cc;
    278   }
    279 
    280   /// NewCallbackWithOutput() allocates a new, single-use
    281   /// <code>CompletionCallback</code> where the browser will pass an additional
    282   /// parameter containing the result of the request. The
    283   /// <code>CompletionCallback</code> must be run in order for the memory
    284   /// allocated by the methods to be freed.
    285   ///
    286   /// @param[in] method The method to be invoked upon completion of the
    287   /// operation.
    288   ///
    289   /// @return A <code>CompletionCallback</code>.
    290   template <typename Output>
    291   CompletionCallbackWithOutput<
    292       typename internal::TypeUnwrapper<Output>::StorageType>
    293   NewCallbackWithOutput(void (T::*method)(int32_t, Output)) {
    294     return NewCallbackWithOutputHelper(new DispatcherWithOutput0<
    295         typename internal::TypeUnwrapper<Output>::StorageType,
    296         void (T::*)(int32_t, Output)>(method));
    297   }
    298 
    299   /// NewCallback() allocates a new, single-use <code>CompletionCallback</code>.
    300   /// The <code>CompletionCallback</code> must be run in order for the memory
    301   /// allocated by the methods to be freed.
    302   ///
    303   /// @param[in] method The method to be invoked upon completion of the
    304   /// operation. Method should be of type:
    305   /// <code>void (T::*)(int32_t result, const A& a)</code>
    306   ///
    307   /// @param[in] a Passed to <code>method</code> when the completion callback
    308   /// runs.
    309   ///
    310   /// @return A <code>CompletionCallback</code>.
    311   template <typename Method, typename A>
    312   CompletionCallback NewCallback(Method method, const A& a) {
    313     return NewCallbackHelper(new Dispatcher1<Method, A>(method, a));
    314   }
    315 
    316   /// NewOptionalCallback() allocates a new, single-use
    317   /// <code>CompletionCallback</code> that might not run if the method
    318   /// taking it can complete synchronously. Thus, if after passing the
    319   /// CompletionCallback to a Pepper method, the method does not return
    320   /// PP_OK_COMPLETIONPENDING, then you should manually call the
    321   /// CompletionCallback's Run method, or memory will be leaked.
    322   ///
    323   /// @param[in] method The method to be invoked upon completion of the
    324   /// operation. Method should be of type:
    325   /// <code>void (T::*)(int32_t result, const A& a)</code>
    326   ///
    327   /// @param[in] a Passed to <code>method</code> when the completion callback
    328   /// runs.
    329   ///
    330   /// @return A <code>CompletionCallback</code>.
    331   template <typename Method, typename A>
    332   CompletionCallback NewOptionalCallback(Method method, const A& a) {
    333     CompletionCallback cc = NewCallback(method, a);
    334     cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL);
    335     return cc;
    336   }
    337 
    338   /// NewCallbackWithOutput() allocates a new, single-use
    339   /// <code>CompletionCallback</code> where the browser will pass an additional
    340   /// parameter containing the result of the request. The
    341   /// <code>CompletionCallback</code> must be run in order for the memory
    342   /// allocated by the methods to be freed.
    343   ///
    344   /// @param[in] method The method to be invoked upon completion of the
    345   /// operation.
    346   ///
    347   /// @param[in] a Passed to <code>method</code> when the completion callback
    348   /// runs.
    349   ///
    350   /// @return A <code>CompletionCallback</code>.
    351   template <typename Output, typename A>
    352   CompletionCallbackWithOutput<
    353       typename internal::TypeUnwrapper<Output>::StorageType>
    354   NewCallbackWithOutput(void (T::*method)(int32_t, Output, A),
    355                         const A& a) {
    356     return NewCallbackWithOutputHelper(new DispatcherWithOutput1<
    357         typename internal::TypeUnwrapper<Output>::StorageType,
    358         void (T::*)(int32_t, Output, A),
    359         typename internal::TypeUnwrapper<A>::StorageType>(method, a));
    360   }
    361 
    362   /// NewCallback() allocates a new, single-use
    363   /// <code>CompletionCallback</code>.
    364   /// The <code>CompletionCallback</code> must be run in order for the memory
    365   /// allocated by the methods to be freed.
    366   ///
    367   /// @param method The method taking the callback. Method should be of type:
    368   /// <code>void (T::*)(int32_t result, const A& a, const B& b)</code>
    369   ///
    370   /// @param[in] a Passed to <code>method</code> when the completion callback
    371   /// runs.
    372   ///
    373   /// @param[in] b Passed to <code>method</code> when the completion callback
    374   /// runs.
    375   ///
    376   /// @return A <code>CompletionCallback</code>.
    377   template <typename Method, typename A, typename B>
    378   CompletionCallback NewCallback(Method method, const A& a, const B& b) {
    379     return NewCallbackHelper(new Dispatcher2<Method, A, B>(method, a, b));
    380   }
    381 
    382   /// NewOptionalCallback() allocates a new, single-use
    383   /// <code>CompletionCallback</code> that might not run if the method
    384   /// taking it can complete synchronously. Thus, if after passing the
    385   /// CompletionCallback to a Pepper method, the method does not return
    386   /// PP_OK_COMPLETIONPENDING, then you should manually call the
    387   /// CompletionCallback's Run method, or memory will be leaked.
    388   ///
    389   /// @param[in] method The method taking the callback. Method should be of
    390   /// type:
    391   /// <code>void (T::*)(int32_t result, const A& a, const B& b)</code>
    392   ///
    393   /// @param[in] a Passed to <code>method</code> when the completion callback
    394   /// runs.
    395   ///
    396   /// @param[in] b Passed to <code>method</code> when the completion callback
    397   /// runs.
    398   ///
    399   /// @return A <code>CompletionCallback</code>.
    400   template <typename Method, typename A, typename B>
    401   CompletionCallback NewOptionalCallback(Method method, const A& a,
    402                                          const B& b) {
    403     CompletionCallback cc = NewCallback(method, a, b);
    404     cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL);
    405     return cc;
    406   }
    407 
    408   /// NewCallbackWithOutput() allocates a new, single-use
    409   /// <code>CompletionCallback</code> where the browser will pass an additional
    410   /// parameter containing the result of the request. The
    411   /// <code>CompletionCallback</code> must be run in order for the memory
    412   /// allocated by the methods to be freed.
    413   ///
    414   /// @param[in] method The method to be invoked upon completion of the
    415   /// operation.
    416   ///
    417   /// @param[in] a Passed to <code>method</code> when the completion callback
    418   /// runs.
    419   ///
    420   /// @param[in] b Passed to <code>method</code> when the completion callback
    421   /// runs.
    422   ///
    423   /// @return A <code>CompletionCallback</code>.
    424   template <typename Output, typename A, typename B>
    425   CompletionCallbackWithOutput<
    426       typename internal::TypeUnwrapper<Output>::StorageType>
    427   NewCallbackWithOutput(void (T::*method)(int32_t, Output, A, B),
    428                         const A& a,
    429                         const B& b) {
    430     return NewCallbackWithOutputHelper(new DispatcherWithOutput2<
    431         typename internal::TypeUnwrapper<Output>::StorageType,
    432         void (T::*)(int32_t, Output, A, B),
    433         typename internal::TypeUnwrapper<A>::StorageType,
    434         typename internal::TypeUnwrapper<B>::StorageType>(method, a, b));
    435   }
    436 
    437   /// NewCallback() allocates a new, single-use
    438   /// <code>CompletionCallback</code>.
    439   /// The <code>CompletionCallback</code> must be run in order for the memory
    440   /// allocated by the methods to be freed.
    441   ///
    442   /// @param method The method taking the callback. Method should be of type:
    443   /// <code>
    444   /// void (T::*)(int32_t result, const A& a, const B& b, const C& c)
    445   /// </code>
    446   ///
    447   /// @param[in] a Passed to <code>method</code> when the completion callback
    448   /// runs.
    449   ///
    450   /// @param[in] b Passed to <code>method</code> when the completion callback
    451   /// runs.
    452   ///
    453   /// @param[in] c Passed to <code>method</code> when the completion callback
    454   /// runs.
    455   ///
    456   /// @return A <code>CompletionCallback</code>.
    457   template <typename Method, typename A, typename B, typename C>
    458   CompletionCallback NewCallback(Method method, const A& a, const B& b,
    459                                  const C& c) {
    460     return NewCallbackHelper(new Dispatcher3<Method, A, B, C>(method, a, b, c));
    461   }
    462 
    463   /// NewOptionalCallback() allocates a new, single-use
    464   /// <code>CompletionCallback</code> that might not run if the method
    465   /// taking it can complete synchronously. Thus, if after passing the
    466   /// CompletionCallback to a Pepper method, the method does not return
    467   /// PP_OK_COMPLETIONPENDING, then you should manually call the
    468   /// CompletionCallback's Run method, or memory will be leaked.
    469   ///
    470   /// @param[in] method The method taking the callback. Method should be of
    471   /// type:
    472   /// <code>
    473   /// void (T::*)(int32_t result, const A& a, const B& b, const C& c)
    474   /// </code>
    475   ///
    476   /// @param[in] a Passed to <code>method</code> when the completion callback
    477   /// runs.
    478   ///
    479   /// @param[in] b Passed to <code>method</code> when the completion callback
    480   /// runs.
    481   ///
    482   /// @param[in] c Passed to <code>method</code> when the completion callback
    483   /// runs.
    484   ///
    485   /// @return A <code>CompletionCallback</code>.
    486   template <typename Method, typename A, typename B, typename C>
    487   CompletionCallback NewOptionalCallback(Method method, const A& a,
    488                                          const B& b, const C& c) {
    489     CompletionCallback cc = NewCallback(method, a, b, c);
    490     cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL);
    491     return cc;
    492   }
    493 
    494   /// NewCallbackWithOutput() allocates a new, single-use
    495   /// <code>CompletionCallback</code> where the browser will pass an additional
    496   /// parameter containing the result of the request. The
    497   /// <code>CompletionCallback</code> must be run in order for the memory
    498   /// allocated by the methods to be freed.
    499   ///
    500   /// @param method The method to be run.
    501   ///
    502   /// @param[in] a Passed to <code>method</code> when the completion callback
    503   /// runs.
    504   ///
    505   /// @param[in] b Passed to <code>method</code> when the completion callback
    506   /// runs.
    507   ///
    508   /// @param[in] c Passed to <code>method</code> when the completion callback
    509   /// runs.
    510   ///
    511   /// @return A <code>CompletionCallback</code>.
    512   template <typename Output, typename A, typename B, typename C>
    513   CompletionCallbackWithOutput<
    514       typename internal::TypeUnwrapper<Output>::StorageType>
    515   NewCallbackWithOutput(void (T::*method)(int32_t, Output, A, B, C),
    516                         const A& a,
    517                         const B& b,
    518                         const C& c) {
    519     return NewCallbackWithOutputHelper(new DispatcherWithOutput3<
    520         typename internal::TypeUnwrapper<Output>::StorageType,
    521         void (T::*)(int32_t, Output, A, B, C),
    522         typename internal::TypeUnwrapper<A>::StorageType,
    523         typename internal::TypeUnwrapper<B>::StorageType,
    524         typename internal::TypeUnwrapper<C>::StorageType>(method, a, b, c));
    525   }
    526 
    527  private:
    528   class BackPointer {
    529    public:
    530     typedef CompletionCallbackFactory<T, ThreadTraits> FactoryType;
    531 
    532     explicit BackPointer(FactoryType* factory)
    533         : factory_(factory) {
    534     }
    535 
    536     void AddRef() {
    537       ref_.AddRef();
    538     }
    539 
    540     void Release() {
    541       if (ref_.Release() == 0)
    542         delete this;
    543     }
    544 
    545     void DropFactory() {
    546       factory_ = NULL;
    547     }
    548 
    549     T* GetObject() {
    550       return factory_ ? factory_->GetObject() : NULL;
    551     }
    552 
    553    private:
    554     typename ThreadTraits::RefCount ref_;
    555     FactoryType* factory_;
    556   };
    557 
    558   template <typename Dispatcher>
    559   class CallbackData {
    560    public:
    561     // Takes ownership of the given dispatcher pointer.
    562     CallbackData(BackPointer* back_pointer, Dispatcher* dispatcher)
    563         : back_pointer_(back_pointer),
    564           dispatcher_(dispatcher) {
    565       back_pointer_->AddRef();
    566     }
    567 
    568     ~CallbackData() {
    569       back_pointer_->Release();
    570       delete dispatcher_;
    571     }
    572 
    573     Dispatcher* dispatcher() { return dispatcher_; }
    574 
    575     static void Thunk(void* user_data, int32_t result) {
    576       Self* self = static_cast<Self*>(user_data);
    577       T* object = self->back_pointer_->GetObject();
    578 
    579       // Please note that |object| may be NULL at this point. But we still need
    580       // to call into Dispatcher::operator() in that case, so that it can do
    581       // necessary cleanup.
    582       (*self->dispatcher_)(object, result);
    583 
    584       delete self;
    585     }
    586 
    587    private:
    588     typedef CallbackData<Dispatcher> Self;
    589     BackPointer* back_pointer_;  // We own a ref to this refcounted object.
    590     Dispatcher* dispatcher_;  // We own this pointer.
    591 
    592     // Disallow copying & assignment.
    593     CallbackData(const CallbackData<Dispatcher>&);
    594     CallbackData<Dispatcher>& operator=(const CallbackData<Dispatcher>&);
    595   };
    596 
    597   template <typename Method>
    598   class Dispatcher0 {
    599    public:
    600     Dispatcher0() : method_(NULL) {}
    601     explicit Dispatcher0(Method method) : method_(method) {
    602     }
    603     void operator()(T* object, int32_t result) {
    604       if (object)
    605         (object->*method_)(result);
    606     }
    607    private:
    608     Method method_;
    609   };
    610 
    611   template <typename Output, typename Method>
    612   class DispatcherWithOutput0 {
    613    public:
    614     typedef Output OutputType;
    615     typedef internal::CallbackOutputTraits<Output> Traits;
    616 
    617     DispatcherWithOutput0()
    618         : method_(NULL),
    619           output_() {
    620       Traits::Initialize(&output_);
    621     }
    622     DispatcherWithOutput0(Method method)
    623         : method_(method),
    624           output_() {
    625       Traits::Initialize(&output_);
    626     }
    627     void operator()(T* object, int32_t result) {
    628       // We must call Traits::StorageToPluginArg() even if we don't need to call
    629       // the callback anymore, otherwise we may leak resource or var references.
    630       if (object)
    631         (object->*method_)(result, Traits::StorageToPluginArg(output_));
    632       else
    633         Traits::StorageToPluginArg(output_);
    634     }
    635     typename Traits::StorageType* output() {
    636       return &output_;
    637     }
    638    private:
    639     Method method_;
    640 
    641     typename Traits::StorageType output_;
    642   };
    643 
    644   template <typename Method, typename A>
    645   class Dispatcher1 {
    646    public:
    647     Dispatcher1()
    648         : method_(NULL),
    649           a_() {
    650     }
    651     Dispatcher1(Method method, const A& a)
    652         : method_(method),
    653           a_(a) {
    654     }
    655     void operator()(T* object, int32_t result) {
    656       if (object)
    657         (object->*method_)(result, a_);
    658     }
    659    private:
    660     Method method_;
    661     A a_;
    662   };
    663 
    664   template <typename Output, typename Method, typename A>
    665   class DispatcherWithOutput1 {
    666    public:
    667     typedef Output OutputType;
    668     typedef internal::CallbackOutputTraits<Output> Traits;
    669 
    670     DispatcherWithOutput1()
    671         : method_(NULL),
    672           a_(),
    673           output_() {
    674       Traits::Initialize(&output_);
    675     }
    676     DispatcherWithOutput1(Method method, const A& a)
    677         : method_(method),
    678           a_(a),
    679           output_() {
    680       Traits::Initialize(&output_);
    681     }
    682     void operator()(T* object, int32_t result) {
    683       // We must call Traits::StorageToPluginArg() even if we don't need to call
    684       // the callback anymore, otherwise we may leak resource or var references.
    685       if (object)
    686         (object->*method_)(result, Traits::StorageToPluginArg(output_), a_);
    687       else
    688         Traits::StorageToPluginArg(output_);
    689     }
    690     typename Traits::StorageType* output() {
    691       return &output_;
    692     }
    693    private:
    694     Method method_;
    695     A a_;
    696 
    697     typename Traits::StorageType output_;
    698   };
    699 
    700   template <typename Method, typename A, typename B>
    701   class Dispatcher2 {
    702    public:
    703     Dispatcher2()
    704         : method_(NULL),
    705           a_(),
    706           b_() {
    707     }
    708     Dispatcher2(Method method, const A& a, const B& b)
    709         : method_(method),
    710           a_(a),
    711           b_(b) {
    712     }
    713     void operator()(T* object, int32_t result) {
    714       if (object)
    715         (object->*method_)(result, a_, b_);
    716     }
    717    private:
    718     Method method_;
    719     A a_;
    720     B b_;
    721   };
    722 
    723   template <typename Output, typename Method, typename A, typename B>
    724   class DispatcherWithOutput2 {
    725    public:
    726     typedef Output OutputType;
    727     typedef internal::CallbackOutputTraits<Output> Traits;
    728 
    729     DispatcherWithOutput2()
    730         : method_(NULL),
    731           a_(),
    732           b_(),
    733           output_() {
    734       Traits::Initialize(&output_);
    735     }
    736     DispatcherWithOutput2(Method method, const A& a, const B& b)
    737         : method_(method),
    738           a_(a),
    739           b_(b),
    740           output_() {
    741       Traits::Initialize(&output_);
    742     }
    743     void operator()(T* object, int32_t result) {
    744       // We must call Traits::StorageToPluginArg() even if we don't need to call
    745       // the callback anymore, otherwise we may leak resource or var references.
    746       if (object)
    747         (object->*method_)(result, Traits::StorageToPluginArg(output_), a_, b_);
    748       else
    749         Traits::StorageToPluginArg(output_);
    750     }
    751     typename Traits::StorageType* output() {
    752       return &output_;
    753     }
    754    private:
    755     Method method_;
    756     A a_;
    757     B b_;
    758 
    759     typename Traits::StorageType output_;
    760   };
    761 
    762   template <typename Method, typename A, typename B, typename C>
    763   class Dispatcher3 {
    764    public:
    765     Dispatcher3()
    766         : method_(NULL),
    767           a_(),
    768           b_(),
    769           c_() {
    770     }
    771     Dispatcher3(Method method, const A& a, const B& b, const C& c)
    772         : method_(method),
    773           a_(a),
    774           b_(b),
    775           c_(c) {
    776     }
    777     void operator()(T* object, int32_t result) {
    778       if (object)
    779         (object->*method_)(result, a_, b_, c_);
    780     }
    781    private:
    782     Method method_;
    783     A a_;
    784     B b_;
    785     C c_;
    786   };
    787 
    788   template <typename Output, typename Method, typename A, typename B,
    789             typename C>
    790   class DispatcherWithOutput3 {
    791    public:
    792     typedef Output OutputType;
    793     typedef internal::CallbackOutputTraits<Output> Traits;
    794 
    795     DispatcherWithOutput3()
    796         : method_(NULL),
    797           a_(),
    798           b_(),
    799           c_(),
    800           output_() {
    801       Traits::Initialize(&output_);
    802     }
    803     DispatcherWithOutput3(Method method, const A& a, const B& b, const C& c)
    804         : method_(method),
    805           a_(a),
    806           b_(b),
    807           c_(c),
    808           output_() {
    809       Traits::Initialize(&output_);
    810     }
    811     void operator()(T* object, int32_t result) {
    812       // We must call Traits::StorageToPluginArg() even if we don't need to call
    813       // the callback anymore, otherwise we may leak resource or var references.
    814       if (object) {
    815         (object->*method_)(result, Traits::StorageToPluginArg(output_),
    816                            a_, b_, c_);
    817       } else {
    818         Traits::StorageToPluginArg(output_);
    819       }
    820     }
    821     typename Traits::StorageType* output() {
    822       return &output_;
    823     }
    824    private:
    825     Method method_;
    826     A a_;
    827     B b_;
    828     C c_;
    829 
    830     typename Traits::StorageType output_;
    831   };
    832 
    833   // Creates the back pointer object and takes a reference to it. This assumes
    834   // either that the lock is held or that it is not needed.
    835   void InitBackPointer() {
    836     back_pointer_ = new BackPointer(this);
    837     back_pointer_->AddRef();
    838   }
    839 
    840   // Releases our reference to the back pointer object and clears the pointer.
    841   // This assumes either that the lock is held or that it is not needed.
    842   void ResetBackPointer() {
    843     back_pointer_->DropFactory();
    844     back_pointer_->Release();
    845     back_pointer_ = NULL;
    846   }
    847 
    848   // Takes ownership of the dispatcher pointer, which should be heap allocated.
    849   template <typename Dispatcher>
    850   CompletionCallback NewCallbackHelper(Dispatcher* dispatcher) {
    851     typename ThreadTraits::AutoLock lock(lock_);
    852 
    853     PP_DCHECK(object_);  // Expects a non-null object!
    854     return CompletionCallback(
    855         &CallbackData<Dispatcher>::Thunk,
    856         new CallbackData<Dispatcher>(back_pointer_, dispatcher));
    857   }
    858 
    859   // Takes ownership of the dispatcher pointer, which should be heap allocated.
    860   template <typename Dispatcher> CompletionCallbackWithOutput<
    861       typename internal::TypeUnwrapper<
    862           typename Dispatcher::OutputType>::StorageType>
    863   NewCallbackWithOutputHelper(Dispatcher* dispatcher) {
    864     typename ThreadTraits::AutoLock lock(lock_);
    865 
    866     PP_DCHECK(object_);  // Expects a non-null object!
    867     CallbackData<Dispatcher>* data =
    868         new CallbackData<Dispatcher>(back_pointer_, dispatcher);
    869 
    870     return CompletionCallbackWithOutput<typename Dispatcher::OutputType>(
    871         &CallbackData<Dispatcher>::Thunk,
    872         data,
    873         data->dispatcher()->output());
    874   }
    875 
    876   // Disallowed:
    877   CompletionCallbackFactory(const CompletionCallbackFactory&);
    878   CompletionCallbackFactory& operator=(const CompletionCallbackFactory&);
    879 
    880   // Never changed once initialized so does not need protection by the lock.
    881   T* object_;
    882 
    883   // Protects the back pointer.
    884   typename ThreadTraits::Lock lock_;
    885 
    886   // Protected by the lock. This will get reset when you do CancelAll, for
    887   // example.
    888   BackPointer* back_pointer_;
    889 };
    890 
    891 }  // namespace pp
    892 
    893 #endif  // PPAPI_UTILITY_COMPLETION_CALLBACK_FACTORY_H_
    894