Home | History | Annotate | Download | only in cpp
      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_CPP_COMPLETION_CALLBACK_H_
      6 #define PPAPI_CPP_COMPLETION_CALLBACK_H_
      7 
      8 #include "ppapi/c/pp_completion_callback.h"
      9 #include "ppapi/c/pp_errors.h"
     10 #include "ppapi/cpp/logging.h"
     11 #include "ppapi/cpp/module.h"
     12 #include "ppapi/cpp/output_traits.h"
     13 
     14 /// @file
     15 /// This file defines the API to create and run a callback.
     16 namespace pp {
     17 
     18 /// This API enables you to implement and receive callbacks when
     19 /// Pepper operations complete asynchronously.
     20 ///
     21 /// You can create these objects yourself, but it is most common to use the
     22 /// CompletionCallbackFactory to allow the callbacks to call class member
     23 /// functions.
     24 class CompletionCallback {
     25  public:
     26   /// The default constructor will create a blocking
     27   /// <code>CompletionCallback</code> that can be passed to a method to
     28   /// indicate that the calling thread should be blocked until the asynchronous
     29   /// operation corresponding to the method completes.
     30   ///
     31   /// <strong>Note:</strong> Blocking completion callbacks are only allowed from
     32   /// from background threads.
     33   CompletionCallback() {
     34     cc_ = PP_BlockUntilComplete();
     35   }
     36 
     37   /// A constructor for creating a <code>CompletionCallback</code>.
     38   ///
     39   /// @param[in] func The function to be called on completion.
     40   /// @param[in] user_data The user data to be passed to the callback function.
     41   /// This is optional and is typically used to help track state in case of
     42   /// multiple pending callbacks.
     43   CompletionCallback(PP_CompletionCallback_Func func, void* user_data) {
     44     cc_ = PP_MakeCompletionCallback(func, user_data);
     45   }
     46 
     47   /// A constructor for creating a <code>CompletionCallback</code> with
     48   /// specified flags.
     49   ///
     50   /// @param[in] func The function to be called on completion.
     51   /// @param[in] user_data The user data to be passed to the callback function.
     52   /// This is optional and is typically used to help track state in case of
     53   /// multiple pending callbacks.
     54   /// @param[in] flags Bit field combination of
     55   /// <code>PP_CompletionCallback_Flag</code> flags used to control how
     56   /// non-NULL callbacks are scheduled by asynchronous methods.
     57   CompletionCallback(PP_CompletionCallback_Func func, void* user_data,
     58                      int32_t flags) {
     59     cc_ = PP_MakeCompletionCallback(func, user_data);
     60     cc_.flags = flags;
     61   }
     62 
     63   /// The set_flags() function is used to set the flags used to control
     64   /// how non-NULL callbacks are scheduled by asynchronous methods.
     65   ///
     66   /// @param[in] flags Bit field combination of
     67   /// <code>PP_CompletionCallback_Flag</code> flags used to control how
     68   /// non-NULL callbacks are scheduled by asynchronous methods.
     69   void set_flags(int32_t flags) { cc_.flags = flags; }
     70 
     71   /// Run() is used to run the <code>CompletionCallback</code>.
     72   /// Normally, the system runs a <code>CompletionCallback</code> after an
     73   /// asynchronous operation completes, but programs may wish to run the
     74   /// <code>CompletionCallback</code> manually in order to reuse the same code
     75   /// paths.
     76   ///
     77   /// @param[in] result The result of the operation to be passed to the
     78   /// callback function. Non-positive values correspond to the error codes
     79   /// from <code>pp_errors.h</code> (excluding
     80   /// <code>PP_OK_COMPLETIONPENDING</code>). Positive values indicate
     81   /// additional information such as bytes read.
     82   void Run(int32_t result) {
     83     PP_DCHECK(cc_.func);
     84     PP_RunCompletionCallback(&cc_, result);
     85   }
     86 
     87   /// RunAndClear() is used to run the <code>CompletionCallback</code> and
     88   /// clear out the callback so that it cannot be run a second time.
     89   ///
     90   /// @param[in] result The result of the operation to be passed to the
     91   /// callback function. Non-positive values correspond to the error codes
     92   /// from <code>pp_errors.h</code> (excluding
     93   /// <code>PP_OK_COMPLETIONPENDING</code>). Positive values indicate
     94   /// additional information such as bytes read.
     95   void RunAndClear(int32_t result) {
     96     PP_DCHECK(cc_.func);
     97     PP_RunAndClearCompletionCallback(&cc_, result);
     98   }
     99 
    100   /// IsOptional() is used to determine the setting of the
    101   /// <code>PP_COMPLETIONCALLBACK_FLAG_OPTIONAL</code> flag. This flag allows
    102   /// any method taking such callback to complete synchronously
    103   /// and not call the callback if the operation would not block. This is useful
    104   /// when performance is an issue, and the operation bandwidth should not be
    105   /// limited to the processing speed of the message loop.
    106   ///
    107   /// On synchronous method completion, the completion result will be returned
    108   /// by the method itself. Otherwise, the method will return
    109   /// PP_OK_COMPLETIONPENDING, and the callback will be invoked asynchronously
    110   /// on the same thread where the PPB method was invoked.
    111   ///
    112   /// @return true if this callback is optional, otherwise false.
    113   bool IsOptional() const {
    114     return (cc_.func == NULL ||
    115             (cc_.flags & PP_COMPLETIONCALLBACK_FLAG_OPTIONAL) != 0);
    116   }
    117 
    118   /// The pp_completion_callback() function returns the underlying
    119   /// <code>PP_CompletionCallback</code>
    120   ///
    121   /// @return A <code>PP_CompletionCallback</code>.
    122   const PP_CompletionCallback& pp_completion_callback() const { return cc_; }
    123 
    124   /// The flags() function returns flags used to control how non-NULL callbacks
    125   /// are scheduled by asynchronous methods.
    126   ///
    127   /// @return An int32_t containing a bit field combination of
    128   /// <code>PP_CompletionCallback_Flag</code> flags.
    129   int32_t flags() const { return cc_.flags; }
    130 
    131   /// MayForce() is used when implementing functions taking callbacks.
    132   /// If the callback is required and <code>result</code> indicates that it has
    133   /// not been scheduled, it will be forced on the main thread.
    134   ///
    135   /// <strong>Example:</strong>
    136   ///
    137   /// @code
    138   ///
    139   /// int32_t OpenURL(pp::URLLoader* loader,
    140   ///                 pp::URLRequestInfo* url_request_info,
    141   ///                 const CompletionCallback& cc) {
    142   ///   if (loader == NULL || url_request_info == NULL)
    143   ///     return cc.MayForce(PP_ERROR_BADRESOURCE);
    144   ///   return loader->Open(*loader, *url_request_info, cc);
    145   /// }
    146   ///
    147   /// @endcode
    148   ///
    149   /// @param[in] result PP_OK_COMPLETIONPENDING or the result of the completed
    150   /// operation to be passed to the callback function. PP_OK_COMPLETIONPENDING
    151   /// indicates that the callback has already been scheduled. Other
    152   /// non-positive values correspond to error codes from
    153   /// <code>pp_errors.h</code>. Positive values indicate additional information
    154   /// such as bytes read.
    155   ///
    156   /// @return <code>PP_OK_COMPLETIONPENDING</code> if the callback has been
    157   /// forced, result parameter otherwise.
    158   int32_t MayForce(int32_t result) const {
    159     if (result == PP_OK_COMPLETIONPENDING || IsOptional())
    160       return result;
    161     // FIXME(dmichael): Use pp::MessageLoop here once it's out of Dev.
    162     Module::Get()->core()->CallOnMainThread(0, *this, result);
    163     return PP_OK_COMPLETIONPENDING;
    164   }
    165 
    166  protected:
    167   PP_CompletionCallback cc_;
    168 };
    169 
    170 /// A CompletionCallbackWithOutput defines a completion callback that
    171 /// additionally stores a pointer to some output data. Some C++ wrappers
    172 /// take a CompletionCallbackWithOutput when the browser is returning a
    173 /// bit of data as part of the function call. The "output" parameter
    174 /// stored in the CompletionCallbackWithOutput will receive the data from
    175 /// the browser.
    176 ///
    177 /// You can create this yourself, but it is most common to use with the
    178 /// CompletionCallbackFactory's NewCallbackWithOutput, which manages the
    179 /// storage for the output parameter for you and passes it as an argument
    180 /// to your callback function.
    181 ///
    182 /// Note that this class doesn't actually do anything with the output data,
    183 /// it just stores a pointer to it. C++ wrapper objects that accept a
    184 /// CompletionCallbackWithOutput will retrieve this pointer and pass it to
    185 /// the browser as the output parameter.
    186 template<typename T>
    187 class CompletionCallbackWithOutput : public CompletionCallback {
    188  public:
    189   /// The type that will actually be stored in the completion callback. In the
    190   /// common case, this will be equal to the template parameter (for example,
    191   /// CompletionCallbackWithOutput<int> would obviously take an int*. However,
    192   /// resources are passed as PP_Resource, vars as PP_Var, and arrays as our
    193   /// special ArrayOutputAdapter object. The CallbackOutputTraits defines
    194   /// specializations for all of these cases.
    195   typedef typename internal::CallbackOutputTraits<T>::StorageType
    196       OutputStorageType;
    197   typedef typename internal::CallbackOutputTraits<T>::APIArgType
    198       APIArgType;
    199 
    200   /// The default constructor will create a blocking
    201   /// <code>CompletionCallback</code> that references the given output
    202   /// data.
    203   ///
    204   /// @param[in] output A pointer to the data associated with the callback. The
    205   /// caller must ensure that this pointer outlives the completion callback.
    206   ///
    207   /// <strong>Note:</strong> Blocking completion callbacks are only allowed from
    208   /// from background threads.
    209   CompletionCallbackWithOutput(OutputStorageType* output)
    210       : CompletionCallback(),
    211         output_(output) {
    212   }
    213 
    214   /// A constructor for creating a <code>CompletionCallback</code> that
    215   /// references the given output data.
    216   ///
    217   /// @param[in] func The function to be called on completion.
    218   /// @param[in] user_data The user data to be passed to the callback function.
    219   /// This is optional and is typically used to help track state in case of
    220   /// multiple pending callbacks.
    221   /// @param[in] output A pointer to the data associated with the callback. The
    222   /// caller must ensure that this pointer outlives the completion callback.
    223   CompletionCallbackWithOutput(PP_CompletionCallback_Func func,
    224                                void* user_data,
    225                                OutputStorageType* output)
    226       : CompletionCallback(func, user_data),
    227         output_(output) {
    228   }
    229 
    230   /// A constructor for creating a <code>CompletionCallback</code> that
    231   /// references the given output data.
    232   ///
    233   /// @param[in] func The function to be called on completion.
    234   ///
    235   /// @param[in] user_data The user data to be passed to the callback function.
    236   /// This is optional and is typically used to help track state in case of
    237   /// multiple pending callbacks.
    238   ///
    239   /// @param[in] flags Bit field combination of
    240   /// <code>PP_CompletionCallback_Flag</code> flags used to control how
    241   /// non-NULL callbacks are scheduled by asynchronous methods.
    242   ///
    243   /// @param[in] output A pointer to the data associated with the callback. The
    244   /// caller must ensure that this pointer outlives the completion callback.
    245   CompletionCallbackWithOutput(PP_CompletionCallback_Func func,
    246                                void* user_data,
    247                                int32_t flags,
    248                                OutputStorageType* output)
    249       : CompletionCallback(func, user_data, flags),
    250         output_(output) {
    251   }
    252 
    253   APIArgType output() const {
    254     return internal::CallbackOutputTraits<T>::StorageToAPIArg(*output_);
    255   }
    256 
    257  private:
    258   OutputStorageType* output_;
    259 };
    260 
    261 /// BlockUntilComplete() is used in place of an actual completion callback
    262 /// to request blocking behavior. If specified, the calling thread will block
    263 /// until the function completes. Blocking completion callbacks are only
    264 /// allowed from background threads.
    265 ///
    266 /// @return A <code>CompletionCallback</code> corresponding to a NULL callback.
    267 inline CompletionCallback BlockUntilComplete() {
    268   // Note: Explicitly inlined to avoid link errors when included into
    269   // ppapi_proxy and ppapi_cpp_objects.
    270   return CompletionCallback();
    271 }
    272 
    273 }  // namespace pp
    274 
    275 #endif  // PPAPI_CPP_COMPLETION_CALLBACK_H_
    276