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 
6 /* From pp_completion_callback.idl modified Thu May  9 14:59:57 2013. */
7 
8 #ifndef PPAPI_C_PP_COMPLETION_CALLBACK_H_
9 #define PPAPI_C_PP_COMPLETION_CALLBACK_H_
10 
11 #include "ppapi/c/pp_macros.h"
12 #include "ppapi/c/pp_stdint.h"
13 
14 /**
15  * @file
16  * This file defines the API to create and run a callback.
17  */
18 
19 
20 /**
21  * @addtogroup Typedefs
22  * @{
23  */
24 /**
25  * This typedef defines the signature that you implement to receive callbacks
26  * on asynchronous completion of an operation.
27  *
28  * @param[in] user_data A pointer to user data passed to a callback function.
29  * @param[in] result If result is 0 (PP_OK), the operation succeeded.  Negative
30  * values (other than -1 or PP_OK_COMPLETE) indicate error and are specified
31  * in pp_errors.h. Positive values for result usually indicate success and have
32  * some operation-dependent meaning (such as bytes read).
33  */
34 typedef void (*PP_CompletionCallback_Func)(void* user_data, int32_t result);
35 /**
36  * @}
37  */
38 
39 /**
40  * @addtogroup Enums
41  * @{
42  */
43 /**
44  * This enumeration contains flags used to control how non-NULL callbacks are
45  * scheduled by asynchronous methods.
46  */
47 typedef enum {
48   /**
49    * By default any non-NULL callback will always invoked asynchronously,
50    * on success or error, even if the operation could complete synchronously
51    * without blocking.
52    *
53    * The method taking such callback will always return PP_OK_COMPLETIONPENDING.
54    * The callback will be invoked on the same thread on which the method was
55    * invoked.
56    *
57    * NOTE: If the method taking the callback is invoked on a background
58    * thread that has no valid PPB_MessageLoop resource attached, the system has
59    * no way to run the callback on the correct thread. In this case, a log
60    * message will be emitted and the plugin will be made to crash.
61    */
62   PP_COMPLETIONCALLBACK_FLAG_NONE = 0 << 0,
63   /**
64    * This flag allows any method taking such callback to complete synchronously
65    * and not call the callback if the operation would not block. This is useful
66    * when performance is an issue, and the operation bandwidth should not be
67    * limited to the processing speed of the message loop.
68    *
69    * On synchronous method completion, the completion result will be returned
70    * by the method itself. Otherwise, the method will return
71    * PP_OK_COMPLETIONPENDING, and the callback will be invoked asynchronously on
72    * the same thread on which the method was invoked. If there is no valid
73    * PPB_MessageLoop attached to that thread, and the callback would normally
74    * run asynchronously, the invoked method will return
75    * PP_ERROR_NO_MESSAGE_LOOP.
76    */
77   PP_COMPLETIONCALLBACK_FLAG_OPTIONAL = 1 << 0
78 } PP_CompletionCallback_Flag;
79 PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_CompletionCallback_Flag, 4);
80 /**
81  * @}
82  */
83 
84 /**
85  * @addtogroup Structs
86  * @{
87  */
88 /**
89  * <code>PP_CompletionCallback</code> is a common mechanism for supporting
90  * potentially asynchronous calls in browser interfaces. Any method that takes a
91  * <code>PP_CompletionCallback</code> can be used in one of three different
92  * ways:
93  *   - Required: The callback will always be invoked asynchronously on the
94  *               thread where the associated PPB method was invoked. The method
95  *               will always return PP_OK_COMPLETIONPENDING when a required
96  *               callback, and the callback will be invoked later (barring
97  *               system or thread shutdown; see PPB_MessageLoop for details).
98  *               Required callbacks are the default.
99  *               <br /><br />
100  *               NOTE: If you use a required callback on a background thread,
101  *               you must have created and attached a PPB_MessageLoop.
102  *               Otherwise, the system can not run your callback on that thread,
103  *               and will instead emit a log message and crash your plugin to
104  *               make the problem more obvious.
105  *
106  *   - Optional: The callback may be invoked asynchronously, or the PPB method
107  *               may complete synchronously if it can do so without blocking.
108  *               If the method will complete asynchronously, it will return
109  *               PP_OK_COMPLETIONPENDING. Otherwise, it will complete
110  *               synchronously and return an appropriate code (see below for
111  *               more information on the return code). Optional callbacks are
112  *               generally more difficult to use correctly than Required
113  *               callbacks, but can provide better performance for some APIs
114  *               (especially APIs with buffered reads, such as PPB_URLLoader or
115  *               PPB_FileIO).
116  *               <br /><br />
117  *               NOTE: If you use an optional callback on a background thread,
118  *               and you have not created and attached a PPB_MessageLoop, then
119  *               the method you invoke will fail without running and return
120  *               PP_ERROR_NO_MESSAGE_LOOP.
121  *
122  *   - Blocking: In this case, the callback's function pointer is NULL, and the
123  *               invoked method must complete synchronously. The method will
124  *               run to completion and return an appropriate code when finished
125  *               (see below for more information). Blocking completion
126  *               callbacks are only supported on background threads.
127  *               <br /><br />
128  *               <code>PP_BlockUntilComplete()</code> provides a convenient way
129  *               to specify blocking behavior. Refer to
130  *               <code>PP_BlockUntilComplete</code> for more information.
131  *
132  * When the callback is run asynchronously, the result parameter passed to
133  * <code>func</code> is an int32_t that, if negative indicates an error code
134  * whose meaning is specific to the calling method (refer to
135  * <code>pp_error.h</code> for further information). A positive or 0 value is a
136  * return result indicating success whose meaning depends on the calling method
137  * (e.g. number of bytes read).
138  */
139 struct PP_CompletionCallback {
140   /**
141    * This value is a callback function that will be called, or NULL if this is
142    * a blocking completion callback.
143    */
144   PP_CompletionCallback_Func func;
145   /**
146    * This value is a pointer to user data passed to a callback function.
147    */
148   void* user_data;
149   /**
150    * Flags used to control how non-NULL callbacks are scheduled by
151    * asynchronous methods.
152    */
153   int32_t flags;
154 };
155 /**
156  * @}
157  */
158 
159 #include <stdlib.h>
160 
161 /**
162  * @addtogroup Functions
163  * @{
164  */
165 /**
166  * PP_MakeCompletionCallback() is used to create a
167  * <code>PP_CompletionCallback</code>.
168  *
169  * <strong>Example, creating a Required callback:</strong>
170  *
171  * @code
172  * struct PP_CompletionCallback cc = PP_MakeCompletionCallback(Foo, NULL);
173  * @endcode
174  *
175  * <strong>Example, creating an Optional callback:</strong>
176  *
177  * @code
178  * struct PP_CompletionCallback cc = PP_MakeCompletionCallback(Foo, NULL);
179  * cc.flags = cc.flags | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL;
180  * @endcode
181  *
182  * @param[in] func A <code>PP_CompletionCallback_Func</code> that will be
183  * called.
184  * @param[in] user_data A pointer to user data passed to your callback
185  * function. This is optional and is typically used to help track state
186  * when you may have multiple callbacks pending.
187  *
188  * @return A <code>PP_CompletionCallback</code> structure.
189  */
PP_MakeCompletionCallback(PP_CompletionCallback_Func func,void * user_data)190 PP_INLINE struct PP_CompletionCallback PP_MakeCompletionCallback(
191     PP_CompletionCallback_Func func,
192     void* user_data) {
193   struct PP_CompletionCallback cc;
194   cc.func = func;
195   cc.user_data = user_data;
196   cc.flags = PP_COMPLETIONCALLBACK_FLAG_NONE;
197   return cc;
198 }
199 
200 /**
201  * PP_MakeOptionalCompletionCallback() is used to create a PP_CompletionCallback
202  * with PP_COMPLETIONCALLBACK_FLAG_OPTIONAL set.
203  *
204  * @param[in] func A PP_CompletionCallback_Func to be called on completion.
205  * @param[in] user_data A pointer to user data passed to be passed to the
206  * callback function. This is optional and is typically used to help track state
207  * in case of multiple pending callbacks.
208  *
209  * @return A PP_CompletionCallback structure.
210  */
PP_MakeOptionalCompletionCallback(PP_CompletionCallback_Func func,void * user_data)211 PP_INLINE struct PP_CompletionCallback PP_MakeOptionalCompletionCallback(
212     PP_CompletionCallback_Func func,
213     void* user_data) {
214   struct PP_CompletionCallback cc = PP_MakeCompletionCallback(func, user_data);
215   cc.flags = cc.flags | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL;
216   return cc;
217 }
218 /**
219  * @}
220  */
221 
222 /**
223  * @addtogroup Functions
224  * @{
225  */
226 
227 /**
228  * PP_RunCompletionCallback() is used to run a callback. It invokes
229  * the callback function passing it user data specified on creation and
230  * completion |result|.
231  *
232  * @param[in] cc A pointer to a <code>PP_CompletionCallback</code> that will be
233  * run.
234  * @param[in] result The result of the operation. Non-positive values correspond
235  * to the error codes from pp_errors.h (excluding PP_OK_COMPLETIONPENDING).
236  * Positive values indicate additional information such as bytes read.
237  */
PP_RunCompletionCallback(struct PP_CompletionCallback * cc,int32_t result)238 PP_INLINE void PP_RunCompletionCallback(struct PP_CompletionCallback* cc,
239                                         int32_t result) {
240   cc->func(cc->user_data, result);
241 }
242 
243 /**
244  * @}
245  */
246 
247 /**
248  * @addtogroup Functions
249  * @{
250  */
251 
252  /**
253  * PP_BlockUntilComplete() is used in place of an actual completion callback
254  * to request blocking behavior. If specified, the calling thread will block
255  * until the function completes. Blocking completion callbacks are only allowed
256  * from background threads.
257  *
258  * @return A <code>PP_CompletionCallback</code> structure.
259  */
PP_BlockUntilComplete(void)260 PP_INLINE struct PP_CompletionCallback PP_BlockUntilComplete(void) {
261   return PP_MakeCompletionCallback(NULL, NULL);
262 }
263 
264 /**
265  * PP_RunAndClearCompletionCallback() runs a callback and clears the reference
266  * to that callback.
267  *
268  * This function is used when the null-ness of a completion callback is used as
269  * a signal for whether a completion callback has been registered. In this
270  * case, after the execution of the callback, it should be cleared. However,
271  * this introduces a conflict if the completion callback wants to schedule more
272  * work that involves the same completion callback again (for example, when
273  * reading data from an URLLoader, one would typically queue up another read
274  * callback). As a result, this function clears the pointer
275  * before the provided callback is executed.
276  */
PP_RunAndClearCompletionCallback(struct PP_CompletionCallback * cc,int32_t res)277 PP_INLINE void PP_RunAndClearCompletionCallback(
278     struct PP_CompletionCallback* cc,
279     int32_t res) {
280   struct PP_CompletionCallback temp = *cc;
281   *cc = PP_BlockUntilComplete();
282   PP_RunCompletionCallback(&temp, res);
283 }
284 /**
285  * @}
286  */
287 
288 #endif  /* PPAPI_C_PP_COMPLETION_CALLBACK_H_ */
289 
290