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