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