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 ///
    189 /// NewExtCallbackWithOutput is similar to NewCallbackWithOutput. It creates
    190 /// ext::ExtCompletionCallbackWithOutput instances which are used by APIs within
    191 /// the pp::ext namespace.
    192 template <typename T, typename ThreadTraits = ThreadSafeThreadTraits>
    193 class CompletionCallbackFactory {
    194  public:
    195 
    196   /// This constructor creates a <code>CompletionCallbackFactory</code>
    197   /// bound to an object. If the constructor is called without an argument,
    198   /// the default value of <code>NULL</code> is used. The user then must call
    199   /// Initialize() to initialize the object.
    200   ///
    201   /// param[in] object Optional parameter. An object whose member functions
    202   /// are to be bound to CompletionCallbacks created by this
    203   /// <code>CompletionCallbackFactory</code>. The default value of this
    204   /// parameter is <code>NULL</code>.
    205   explicit CompletionCallbackFactory(T* object = NULL)
    206       : object_(object) {
    207     // Assume that we don't need to lock since construction should be complete
    208     // before the pointer is used on another thread.
    209     InitBackPointer();
    210   }
    211 
    212   /// Destructor.
    213   ~CompletionCallbackFactory() {
    214     // Assume that we don't need to lock since this object should not be used
    215     // from multiple threads during destruction.
    216     ResetBackPointer();
    217   }
    218 
    219   /// CancelAll() cancels all <code>CompletionCallbacks</code> allocated from
    220   /// this factory.
    221   void CancelAll() {
    222     typename ThreadTraits::AutoLock lock(lock_);
    223 
    224     ResetBackPointer();
    225     InitBackPointer();
    226   }
    227 
    228   /// Initialize() binds the <code>CallbackFactory</code> to a particular
    229   /// object. Use this when the object is not available at
    230   /// <code>CallbackFactory</code> creation, and the <code>NULL</code> default
    231   /// is passed to the constructor. The object may only be initialized once,
    232   /// either by the constructor, or by a call to Initialize().
    233   ///
    234   /// This class may not be used on any thread until initialization is complete.
    235   ///
    236   /// @param[in] object The object whose member functions are to be bound to
    237   /// the <code>CompletionCallback</code> created by this
    238   /// <code>CompletionCallbackFactory</code>.
    239   void Initialize(T* object) {
    240     PP_DCHECK(object);
    241     PP_DCHECK(!object_);  // May only initialize once!
    242     object_ = object;
    243   }
    244 
    245   /// GetObject() returns the object that was passed at initialization to
    246   /// Intialize().
    247   ///
    248   /// @return the object passed to the constructor or Intialize().
    249   T* GetObject() {
    250     return object_;
    251   }
    252 
    253   /// NewCallback allocates a new, single-use <code>CompletionCallback</code>.
    254   /// The <code>CompletionCallback</code> must be run in order for the memory
    255   /// allocated by the methods to be freed.
    256   ///
    257   /// @param[in] method The method to be invoked upon completion of the
    258   /// operation.
    259   ///
    260   /// @return A <code>CompletionCallback</code>.
    261   template <typename Method>
    262   CompletionCallback NewCallback(Method method) {
    263     return NewCallbackHelper(new Dispatcher0<Method>(method));
    264   }
    265 
    266   /// NewOptionalCallback() allocates a new, single-use
    267   /// <code>CompletionCallback</code> that might not run if the method
    268   /// taking it can complete synchronously. Thus, if after passing the
    269   /// CompletionCallback to a Pepper method, the method does not return
    270   /// PP_OK_COMPLETIONPENDING, then you should manually call the
    271   /// CompletionCallback's Run method, or memory will be leaked.
    272   ///
    273   /// @param[in] method The method to be invoked upon completion of the
    274   /// operation.
    275   ///
    276   /// @return A <code>CompletionCallback</code>.
    277   template <typename Method>
    278   CompletionCallback NewOptionalCallback(Method method) {
    279     CompletionCallback cc = NewCallback(method);
    280     cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL);
    281     return cc;
    282   }
    283 
    284   /// NewCallbackWithOutput() allocates a new, single-use
    285   /// <code>CompletionCallback</code> where the browser will pass an additional
    286   /// parameter containing the result of the request. The
    287   /// <code>CompletionCallback</code> must be run in order for the memory
    288   /// allocated by the methods to be freed.
    289   ///
    290   /// @param[in] method The method to be invoked upon completion of the
    291   /// operation.
    292   ///
    293   /// @return A <code>CompletionCallback</code>.
    294   template <typename Output>
    295   CompletionCallbackWithOutput<
    296       typename internal::TypeUnwrapper<Output>::StorageType>
    297   NewCallbackWithOutput(void (T::*method)(int32_t, Output)) {
    298     typedef typename internal::TypeUnwrapper<Output>::StorageType
    299         OutputStorageType;
    300     typedef CompletionCallbackWithOutput<OutputStorageType> CallbackType;
    301     typedef DispatcherWithOutput0<
    302         typename CallbackType::TraitsType,
    303         OutputStorageType,
    304         void (T::*)(int32_t, Output)> DispatcherType;
    305     return NewCallbackWithOutputHelper<CallbackType>(
    306         new DispatcherType(method));
    307   }
    308 
    309   /// Similar to NewCallbackWithOutput(), but returns an
    310   /// <code>ext::ExtCompletionCallbackWithOutput</code>.
    311   template <typename Output>
    312   ext::ExtCompletionCallbackWithOutput<
    313       typename internal::TypeUnwrapper<Output>::StorageType>
    314   NewExtCallbackWithOutput(void (T::*method)(int32_t, Output)) {
    315     typedef typename internal::TypeUnwrapper<Output>::StorageType
    316         OutputStorageType;
    317     typedef ext::ExtCompletionCallbackWithOutput<OutputStorageType>
    318         CallbackType;
    319     typedef DispatcherWithOutput0<
    320         typename CallbackType::TraitsType,
    321         OutputStorageType,
    322         void (T::*)(int32_t, Output)> DispatcherType;
    323     return NewCallbackWithOutputHelper<CallbackType>(
    324         new DispatcherType(method));
    325   }
    326 
    327   /// NewCallback() allocates a new, single-use <code>CompletionCallback</code>.
    328   /// The <code>CompletionCallback</code> must be run in order for the memory
    329   /// allocated by the methods to be freed.
    330   ///
    331   /// @param[in] method The method to be invoked upon completion of the
    332   /// operation. Method should be of type:
    333   /// <code>void (T::*)(int32_t result, const A& a)</code>
    334   ///
    335   /// @param[in] a Passed to <code>method</code> when the completion callback
    336   /// runs.
    337   ///
    338   /// @return A <code>CompletionCallback</code>.
    339   template <typename Method, typename A>
    340   CompletionCallback NewCallback(Method method, const A& a) {
    341     return NewCallbackHelper(new Dispatcher1<Method, A>(method, a));
    342   }
    343 
    344   /// NewOptionalCallback() allocates a new, single-use
    345   /// <code>CompletionCallback</code> that might not run if the method
    346   /// taking it can complete synchronously. Thus, if after passing the
    347   /// CompletionCallback to a Pepper method, the method does not return
    348   /// PP_OK_COMPLETIONPENDING, then you should manually call the
    349   /// CompletionCallback's Run method, or memory will be leaked.
    350   ///
    351   /// @param[in] method The method to be invoked upon completion of the
    352   /// operation. Method should be of type:
    353   /// <code>void (T::*)(int32_t result, const A& a)</code>
    354   ///
    355   /// @param[in] a Passed to <code>method</code> when the completion callback
    356   /// runs.
    357   ///
    358   /// @return A <code>CompletionCallback</code>.
    359   template <typename Method, typename A>
    360   CompletionCallback NewOptionalCallback(Method method, const A& a) {
    361     CompletionCallback cc = NewCallback(method, a);
    362     cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL);
    363     return cc;
    364   }
    365 
    366   /// NewCallbackWithOutput() allocates a new, single-use
    367   /// <code>CompletionCallback</code> where the browser will pass an additional
    368   /// parameter containing the result of the request. The
    369   /// <code>CompletionCallback</code> must be run in order for the memory
    370   /// allocated by the methods to be freed.
    371   ///
    372   /// @param[in] method The method to be invoked upon completion of the
    373   /// operation.
    374   ///
    375   /// @param[in] a Passed to <code>method</code> when the completion callback
    376   /// runs.
    377   ///
    378   /// @return A <code>CompletionCallback</code>.
    379   template <typename Output, typename A>
    380   CompletionCallbackWithOutput<
    381       typename internal::TypeUnwrapper<Output>::StorageType>
    382   NewCallbackWithOutput(void (T::*method)(int32_t, Output, A),
    383                         const A& a) {
    384     typedef typename internal::TypeUnwrapper<Output>::StorageType
    385         OutputStorageType;
    386     typedef CompletionCallbackWithOutput<OutputStorageType> CallbackType;
    387     typedef DispatcherWithOutput1<
    388         typename CallbackType::TraitsType,
    389         OutputStorageType,
    390         void (T::*)(int32_t, Output, A),
    391         typename internal::TypeUnwrapper<A>::StorageType> DispatcherType;
    392     return NewCallbackWithOutputHelper<CallbackType>(
    393         new DispatcherType(method, a));
    394   }
    395 
    396   /// Similar to NewCallbackWithOutput(), but returns an
    397   /// <code>ext::ExtCompletionCallbackWithOutput</code>.
    398   template <typename Output, typename A>
    399   ext::ExtCompletionCallbackWithOutput<
    400       typename internal::TypeUnwrapper<Output>::StorageType>
    401   NewExtCallbackWithOutput(void (T::*method)(int32_t, Output, A),
    402                            const A& a) {
    403     typedef typename internal::TypeUnwrapper<Output>::StorageType
    404         OutputStorageType;
    405     typedef ext::ExtCompletionCallbackWithOutput<OutputStorageType>
    406         CallbackType;
    407     typedef DispatcherWithOutput1<
    408         typename CallbackType::TraitsType,
    409         OutputStorageType,
    410         void (T::*)(int32_t, Output, A),
    411         typename internal::TypeUnwrapper<A>::StorageType> DispatcherType;
    412     return NewCallbackWithOutputHelper<CallbackType>(
    413         new DispatcherType(method, a));
    414   }
    415 
    416   /// NewCallback() allocates a new, single-use
    417   /// <code>CompletionCallback</code>.
    418   /// The <code>CompletionCallback</code> must be run in order for the memory
    419   /// allocated by the methods to be freed.
    420   ///
    421   /// @param method The method taking the callback. Method should be of type:
    422   /// <code>void (T::*)(int32_t result, const A& a, const B& b)</code>
    423   ///
    424   /// @param[in] a Passed to <code>method</code> when the completion callback
    425   /// runs.
    426   ///
    427   /// @param[in] b Passed to <code>method</code> when the completion callback
    428   /// runs.
    429   ///
    430   /// @return A <code>CompletionCallback</code>.
    431   template <typename Method, typename A, typename B>
    432   CompletionCallback NewCallback(Method method, const A& a, const B& b) {
    433     return NewCallbackHelper(new Dispatcher2<Method, A, B>(method, a, b));
    434   }
    435 
    436   /// NewOptionalCallback() allocates a new, single-use
    437   /// <code>CompletionCallback</code> that might not run if the method
    438   /// taking it can complete synchronously. Thus, if after passing the
    439   /// CompletionCallback to a Pepper method, the method does not return
    440   /// PP_OK_COMPLETIONPENDING, then you should manually call the
    441   /// CompletionCallback's Run method, or memory will be leaked.
    442   ///
    443   /// @param[in] method The method taking the callback. Method should be of
    444   /// type:
    445   /// <code>void (T::*)(int32_t result, const A& a, const B& b)</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   /// @return A <code>CompletionCallback</code>.
    454   template <typename Method, typename A, typename B>
    455   CompletionCallback NewOptionalCallback(Method method, const A& a,
    456                                          const B& b) {
    457     CompletionCallback cc = NewCallback(method, a, b);
    458     cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL);
    459     return cc;
    460   }
    461 
    462   /// NewCallbackWithOutput() allocates a new, single-use
    463   /// <code>CompletionCallback</code> where the browser will pass an additional
    464   /// parameter containing the result of the request. The
    465   /// <code>CompletionCallback</code> must be run in order for the memory
    466   /// allocated by the methods to be freed.
    467   ///
    468   /// @param[in] method The method to be invoked upon completion of the
    469   /// operation.
    470   ///
    471   /// @param[in] a Passed to <code>method</code> when the completion callback
    472   /// runs.
    473   ///
    474   /// @param[in] b Passed to <code>method</code> when the completion callback
    475   /// runs.
    476   ///
    477   /// @return A <code>CompletionCallback</code>.
    478   template <typename Output, typename A, typename B>
    479   CompletionCallbackWithOutput<
    480       typename internal::TypeUnwrapper<Output>::StorageType>
    481   NewCallbackWithOutput(void (T::*method)(int32_t, Output, A, B),
    482                         const A& a,
    483                         const B& b) {
    484     typedef typename internal::TypeUnwrapper<Output>::StorageType
    485         OutputStorageType;
    486     typedef CompletionCallbackWithOutput<OutputStorageType> CallbackType;
    487     typedef DispatcherWithOutput2<
    488         typename CallbackType::TraitsType,
    489         OutputStorageType,
    490         void (T::*)(int32_t, Output, A, B),
    491         typename internal::TypeUnwrapper<A>::StorageType,
    492         typename internal::TypeUnwrapper<B>::StorageType> DispatcherType;
    493     return NewCallbackWithOutputHelper<CallbackType>(
    494         new DispatcherType(method, a, b));
    495   }
    496 
    497   /// Similar to NewCallbackWithOutput(), but returns an
    498   /// <code>ext::ExtCompletionCallbackWithOutput</code>.
    499   template <typename Output, typename A, typename B>
    500   ext::ExtCompletionCallbackWithOutput<
    501       typename internal::TypeUnwrapper<Output>::StorageType>
    502   NewExtCallbackWithOutput(void (T::*method)(int32_t, Output, A, B),
    503                            const A& a,
    504                            const B& b) {
    505     typedef typename internal::TypeUnwrapper<Output>::StorageType
    506         OutputStorageType;
    507     typedef ext::ExtCompletionCallbackWithOutput<OutputStorageType>
    508         CallbackType;
    509     typedef DispatcherWithOutput2<
    510         typename CallbackType::TraitsType,
    511         OutputStorageType,
    512         void (T::*)(int32_t, Output, A, B),
    513         typename internal::TypeUnwrapper<A>::StorageType,
    514         typename internal::TypeUnwrapper<B>::StorageType> DispatcherType;
    515     return NewCallbackWithOutputHelper<CallbackType>(
    516         new DispatcherType(method, a, b));
    517   }
    518 
    519   /// NewCallback() allocates a new, single-use
    520   /// <code>CompletionCallback</code>.
    521   /// The <code>CompletionCallback</code> must be run in order for the memory
    522   /// allocated by the methods to be freed.
    523   ///
    524   /// @param method The method taking the callback. Method should be of type:
    525   /// <code>
    526   /// void (T::*)(int32_t result, const A& a, const B& b, const C& c)
    527   /// </code>
    528   ///
    529   /// @param[in] a Passed to <code>method</code> when the completion callback
    530   /// runs.
    531   ///
    532   /// @param[in] b Passed to <code>method</code> when the completion callback
    533   /// runs.
    534   ///
    535   /// @param[in] c Passed to <code>method</code> when the completion callback
    536   /// runs.
    537   ///
    538   /// @return A <code>CompletionCallback</code>.
    539   template <typename Method, typename A, typename B, typename C>
    540   CompletionCallback NewCallback(Method method, const A& a, const B& b,
    541                                  const C& c) {
    542     return NewCallbackHelper(new Dispatcher3<Method, A, B, C>(method, a, b, c));
    543   }
    544 
    545   /// NewOptionalCallback() allocates a new, single-use
    546   /// <code>CompletionCallback</code> that might not run if the method
    547   /// taking it can complete synchronously. Thus, if after passing the
    548   /// CompletionCallback to a Pepper method, the method does not return
    549   /// PP_OK_COMPLETIONPENDING, then you should manually call the
    550   /// CompletionCallback's Run method, or memory will be leaked.
    551   ///
    552   /// @param[in] method The method taking the callback. Method should be of
    553   /// type:
    554   /// <code>
    555   /// void (T::*)(int32_t result, const A& a, const B& b, const C& c)
    556   /// </code>
    557   ///
    558   /// @param[in] a Passed to <code>method</code> when the completion callback
    559   /// runs.
    560   ///
    561   /// @param[in] b Passed to <code>method</code> when the completion callback
    562   /// runs.
    563   ///
    564   /// @param[in] c Passed to <code>method</code> when the completion callback
    565   /// runs.
    566   ///
    567   /// @return A <code>CompletionCallback</code>.
    568   template <typename Method, typename A, typename B, typename C>
    569   CompletionCallback NewOptionalCallback(Method method, const A& a,
    570                                          const B& b, const C& c) {
    571     CompletionCallback cc = NewCallback(method, a, b, c);
    572     cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL);
    573     return cc;
    574   }
    575 
    576   /// NewCallbackWithOutput() allocates a new, single-use
    577   /// <code>CompletionCallback</code> where the browser will pass an additional
    578   /// parameter containing the result of the request. The
    579   /// <code>CompletionCallback</code> must be run in order for the memory
    580   /// allocated by the methods to be freed.
    581   ///
    582   /// @param method The method to be run.
    583   ///
    584   /// @param[in] a Passed to <code>method</code> when the completion callback
    585   /// runs.
    586   ///
    587   /// @param[in] b Passed to <code>method</code> when the completion callback
    588   /// runs.
    589   ///
    590   /// @param[in] c Passed to <code>method</code> when the completion callback
    591   /// runs.
    592   ///
    593   /// @return A <code>CompletionCallback</code>.
    594   template <typename Output, typename A, typename B, typename C>
    595   CompletionCallbackWithOutput<
    596       typename internal::TypeUnwrapper<Output>::StorageType>
    597   NewCallbackWithOutput(void (T::*method)(int32_t, Output, A, B, C),
    598                         const A& a,
    599                         const B& b,
    600                         const C& c) {
    601     typedef typename internal::TypeUnwrapper<Output>::StorageType
    602         OutputStorageType;
    603     typedef CompletionCallbackWithOutput<OutputStorageType> CallbackType;
    604     typedef DispatcherWithOutput3<
    605         typename CallbackType::TraitsType,
    606         OutputStorageType,
    607         void (T::*)(int32_t, Output, A, B, C),
    608         typename internal::TypeUnwrapper<A>::StorageType,
    609         typename internal::TypeUnwrapper<B>::StorageType,
    610         typename internal::TypeUnwrapper<C>::StorageType> DispatcherType;
    611     return NewCallbackWithOutputHelper<CallbackType>(
    612         new DispatcherType(method, a, b, c));
    613   }
    614 
    615   /// Similar to NewCallbackWithOutput(), but returns an
    616   /// <code>ext::ExtCompletionCallbackWithOutput</code>.
    617   template <typename Output, typename A, typename B, typename C>
    618   ext::ExtCompletionCallbackWithOutput<
    619       typename internal::TypeUnwrapper<Output>::StorageType>
    620   NewExtCallbackWithOutput(void (T::*method)(int32_t, Output, A, B, C),
    621                            const A& a,
    622                            const B& b,
    623                            const C& c) {
    624     typedef typename internal::TypeUnwrapper<Output>::StorageType
    625         OutputStorageType;
    626     typedef ext::ExtCompletionCallbackWithOutput<OutputStorageType>
    627         CallbackType;
    628     typedef DispatcherWithOutput3<
    629         typename CallbackType::TraitsType,
    630         OutputStorageType,
    631         void (T::*)(int32_t, Output, A, B, C),
    632         typename internal::TypeUnwrapper<A>::StorageType,
    633         typename internal::TypeUnwrapper<B>::StorageType,
    634         typename internal::TypeUnwrapper<C>::StorageType> DispatcherType;
    635     return NewCallbackWithOutputHelper<CallbackType>(
    636         new DispatcherType(method, a, b, c));
    637   }
    638 
    639  private:
    640   class BackPointer {
    641    public:
    642     typedef CompletionCallbackFactory<T, ThreadTraits> FactoryType;
    643 
    644     explicit BackPointer(FactoryType* factory)
    645         : factory_(factory) {
    646     }
    647 
    648     void AddRef() {
    649       ref_.AddRef();
    650     }
    651 
    652     void Release() {
    653       if (ref_.Release() == 0)
    654         delete this;
    655     }
    656 
    657     void DropFactory() {
    658       factory_ = NULL;
    659     }
    660 
    661     T* GetObject() {
    662       return factory_ ? factory_->GetObject() : NULL;
    663     }
    664 
    665    private:
    666     typename ThreadTraits::RefCount ref_;
    667     FactoryType* factory_;
    668   };
    669 
    670   template <typename Dispatcher>
    671   class CallbackData {
    672    public:
    673     // Takes ownership of the given dispatcher pointer.
    674     CallbackData(BackPointer* back_pointer, Dispatcher* dispatcher)
    675         : back_pointer_(back_pointer),
    676           dispatcher_(dispatcher) {
    677       back_pointer_->AddRef();
    678     }
    679 
    680     ~CallbackData() {
    681       back_pointer_->Release();
    682       delete dispatcher_;
    683     }
    684 
    685     Dispatcher* dispatcher() { return dispatcher_; }
    686 
    687     static void Thunk(void* user_data, int32_t result) {
    688       Self* self = static_cast<Self*>(user_data);
    689       T* object = self->back_pointer_->GetObject();
    690 
    691       // Please note that |object| may be NULL at this point. But we still need
    692       // to call into Dispatcher::operator() in that case, so that it can do
    693       // necessary cleanup.
    694       (*self->dispatcher_)(object, result);
    695 
    696       delete self;
    697     }
    698 
    699    private:
    700     typedef CallbackData<Dispatcher> Self;
    701     BackPointer* back_pointer_;  // We own a ref to this refcounted object.
    702     Dispatcher* dispatcher_;  // We own this pointer.
    703 
    704     // Disallow copying & assignment.
    705     CallbackData(const CallbackData<Dispatcher>&);
    706     CallbackData<Dispatcher>& operator=(const CallbackData<Dispatcher>&);
    707   };
    708 
    709   template <typename Method>
    710   class Dispatcher0 {
    711    public:
    712     Dispatcher0() : method_(NULL) {}
    713     explicit Dispatcher0(Method method) : method_(method) {
    714     }
    715     void operator()(T* object, int32_t result) {
    716       if (object)
    717         (object->*method_)(result);
    718     }
    719    private:
    720     Method method_;
    721   };
    722 
    723   template <typename Traits, typename Output, typename Method>
    724   class DispatcherWithOutput0 {
    725    public:
    726     typedef Output OutputType;
    727 
    728     DispatcherWithOutput0()
    729         : method_(NULL),
    730           output_() {
    731       Traits::Initialize(&output_);
    732     }
    733     DispatcherWithOutput0(Method method)
    734         : method_(method),
    735           output_() {
    736       Traits::Initialize(&output_);
    737     }
    738     void operator()(T* object, int32_t result) {
    739       // We must call Traits::StorageToPluginArg() even if we don't need to call
    740       // the callback anymore, otherwise we may leak resource or var references.
    741       if (object)
    742         (object->*method_)(result, Traits::StorageToPluginArg(output_));
    743       else
    744         Traits::StorageToPluginArg(output_);
    745     }
    746     typename Traits::StorageType* output() {
    747       return &output_;
    748     }
    749    private:
    750     Method method_;
    751 
    752     typename Traits::StorageType output_;
    753   };
    754 
    755   template <typename Method, typename A>
    756   class Dispatcher1 {
    757    public:
    758     Dispatcher1()
    759         : method_(NULL),
    760           a_() {
    761     }
    762     Dispatcher1(Method method, const A& a)
    763         : method_(method),
    764           a_(a) {
    765     }
    766     void operator()(T* object, int32_t result) {
    767       if (object)
    768         (object->*method_)(result, a_);
    769     }
    770    private:
    771     Method method_;
    772     A a_;
    773   };
    774 
    775   template <typename Traits, typename Output, typename Method, typename A>
    776   class DispatcherWithOutput1 {
    777    public:
    778     typedef Output OutputType;
    779 
    780     DispatcherWithOutput1()
    781         : method_(NULL),
    782           a_(),
    783           output_() {
    784       Traits::Initialize(&output_);
    785     }
    786     DispatcherWithOutput1(Method method, const A& a)
    787         : method_(method),
    788           a_(a),
    789           output_() {
    790       Traits::Initialize(&output_);
    791     }
    792     void operator()(T* object, int32_t result) {
    793       // We must call Traits::StorageToPluginArg() even if we don't need to call
    794       // the callback anymore, otherwise we may leak resource or var references.
    795       if (object)
    796         (object->*method_)(result, Traits::StorageToPluginArg(output_), a_);
    797       else
    798         Traits::StorageToPluginArg(output_);
    799     }
    800     typename Traits::StorageType* output() {
    801       return &output_;
    802     }
    803    private:
    804     Method method_;
    805     A a_;
    806 
    807     typename Traits::StorageType output_;
    808   };
    809 
    810   template <typename Method, typename A, typename B>
    811   class Dispatcher2 {
    812    public:
    813     Dispatcher2()
    814         : method_(NULL),
    815           a_(),
    816           b_() {
    817     }
    818     Dispatcher2(Method method, const A& a, const B& b)
    819         : method_(method),
    820           a_(a),
    821           b_(b) {
    822     }
    823     void operator()(T* object, int32_t result) {
    824       if (object)
    825         (object->*method_)(result, a_, b_);
    826     }
    827    private:
    828     Method method_;
    829     A a_;
    830     B b_;
    831   };
    832 
    833   template <typename Traits,
    834             typename Output,
    835             typename Method,
    836             typename A,
    837             typename B>
    838   class DispatcherWithOutput2 {
    839    public:
    840     typedef Output OutputType;
    841 
    842     DispatcherWithOutput2()
    843         : method_(NULL),
    844           a_(),
    845           b_(),
    846           output_() {
    847       Traits::Initialize(&output_);
    848     }
    849     DispatcherWithOutput2(Method method, const A& a, const B& b)
    850         : method_(method),
    851           a_(a),
    852           b_(b),
    853           output_() {
    854       Traits::Initialize(&output_);
    855     }
    856     void operator()(T* object, int32_t result) {
    857       // We must call Traits::StorageToPluginArg() even if we don't need to call
    858       // the callback anymore, otherwise we may leak resource or var references.
    859       if (object)
    860         (object->*method_)(result, Traits::StorageToPluginArg(output_), a_, b_);
    861       else
    862         Traits::StorageToPluginArg(output_);
    863     }
    864     typename Traits::StorageType* output() {
    865       return &output_;
    866     }
    867    private:
    868     Method method_;
    869     A a_;
    870     B b_;
    871 
    872     typename Traits::StorageType output_;
    873   };
    874 
    875   template <typename Method, typename A, typename B, typename C>
    876   class Dispatcher3 {
    877    public:
    878     Dispatcher3()
    879         : method_(NULL),
    880           a_(),
    881           b_(),
    882           c_() {
    883     }
    884     Dispatcher3(Method method, const A& a, const B& b, const C& c)
    885         : method_(method),
    886           a_(a),
    887           b_(b),
    888           c_(c) {
    889     }
    890     void operator()(T* object, int32_t result) {
    891       if (object)
    892         (object->*method_)(result, a_, b_, c_);
    893     }
    894    private:
    895     Method method_;
    896     A a_;
    897     B b_;
    898     C c_;
    899   };
    900 
    901   template <typename Traits,
    902             typename Output,
    903             typename Method,
    904             typename A,
    905             typename B,
    906             typename C>
    907   class DispatcherWithOutput3 {
    908    public:
    909     typedef Output OutputType;
    910 
    911     DispatcherWithOutput3()
    912         : method_(NULL),
    913           a_(),
    914           b_(),
    915           c_(),
    916           output_() {
    917       Traits::Initialize(&output_);
    918     }
    919     DispatcherWithOutput3(Method method, const A& a, const B& b, const C& c)
    920         : method_(method),
    921           a_(a),
    922           b_(b),
    923           c_(c),
    924           output_() {
    925       Traits::Initialize(&output_);
    926     }
    927     void operator()(T* object, int32_t result) {
    928       // We must call Traits::StorageToPluginArg() even if we don't need to call
    929       // the callback anymore, otherwise we may leak resource or var references.
    930       if (object) {
    931         (object->*method_)(result, Traits::StorageToPluginArg(output_),
    932                            a_, b_, c_);
    933       } else {
    934         Traits::StorageToPluginArg(output_);
    935       }
    936     }
    937     typename Traits::StorageType* output() {
    938       return &output_;
    939     }
    940    private:
    941     Method method_;
    942     A a_;
    943     B b_;
    944     C c_;
    945 
    946     typename Traits::StorageType output_;
    947   };
    948 
    949   // Creates the back pointer object and takes a reference to it. This assumes
    950   // either that the lock is held or that it is not needed.
    951   void InitBackPointer() {
    952     back_pointer_ = new BackPointer(this);
    953     back_pointer_->AddRef();
    954   }
    955 
    956   // Releases our reference to the back pointer object and clears the pointer.
    957   // This assumes either that the lock is held or that it is not needed.
    958   void ResetBackPointer() {
    959     back_pointer_->DropFactory();
    960     back_pointer_->Release();
    961     back_pointer_ = NULL;
    962   }
    963 
    964   // Takes ownership of the dispatcher pointer, which should be heap allocated.
    965   template <typename Dispatcher>
    966   CompletionCallback NewCallbackHelper(Dispatcher* dispatcher) {
    967     typename ThreadTraits::AutoLock lock(lock_);
    968 
    969     PP_DCHECK(object_);  // Expects a non-null object!
    970     return CompletionCallback(
    971         &CallbackData<Dispatcher>::Thunk,
    972         new CallbackData<Dispatcher>(back_pointer_, dispatcher));
    973   }
    974 
    975   // Takes ownership of the dispatcher pointer, which should be heap allocated.
    976   template <typename Callback, typename Dispatcher>
    977   Callback NewCallbackWithOutputHelper(Dispatcher* dispatcher) {
    978     typename ThreadTraits::AutoLock lock(lock_);
    979 
    980     PP_DCHECK(object_);  // Expects a non-null object!
    981     CallbackData<Dispatcher>* data =
    982         new CallbackData<Dispatcher>(back_pointer_, dispatcher);
    983 
    984     return Callback(&CallbackData<Dispatcher>::Thunk,
    985                     data,
    986                     data->dispatcher()->output());
    987   }
    988 
    989   // Disallowed:
    990   CompletionCallbackFactory(const CompletionCallbackFactory&);
    991   CompletionCallbackFactory& operator=(const CompletionCallbackFactory&);
    992 
    993   // Never changed once initialized so does not need protection by the lock.
    994   T* object_;
    995 
    996   // Protects the back pointer.
    997   typename ThreadTraits::Lock lock_;
    998 
    999   // Protected by the lock. This will get reset when you do CancelAll, for
   1000   // example.
   1001   BackPointer* back_pointer_;
   1002 };
   1003 
   1004 }  // namespace pp
   1005 
   1006 #endif  // PPAPI_UTILITY_COMPLETION_CALLBACK_FACTORY_H_
   1007