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.
16namespace 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.
24class 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.
186template<typename T>
187class 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.
267inline 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