• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
CompletionCallback()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.
CompletionCallback(PP_CompletionCallback_Func func,void * user_data)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.
CompletionCallback(PP_CompletionCallback_Func func,void * user_data,int32_t flags)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.
set_flags(int32_t flags)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.
Run(int32_t result)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.
RunAndClear(int32_t result)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.
IsOptional()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>.
pp_completion_callback()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.
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.
MayForce(int32_t result)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.
CompletionCallbackWithOutput(OutputStorageType * output)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.
CompletionCallbackWithOutput(PP_CompletionCallback_Func func,void * user_data,OutputStorageType * output)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.
CompletionCallbackWithOutput(PP_CompletionCallback_Func func,void * user_data,int32_t flags,OutputStorageType * output)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 
output()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.
BlockUntilComplete()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