| /* Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| /** | |
| * This file defines the API to create and run a callback. | |
| */ | |
| /** | |
| * This typedef defines the signature that you implement to receive callbacks | |
| * on asynchronous completion of an operation. | |
| * | |
| * @param[in] user_data A pointer to user data passed to a callback function. | |
| * @param[in] result If result is 0 (PP_OK), the operation succeeded. Negative | |
| * values (other than -1 or PP_OK_COMPLETE) indicate error and are specified | |
| * in pp_errors.h. Positive values for result usually indicate success and have | |
| * some operation-dependent meaning (such as bytes read). | |
| */ | |
| typedef void PP_CompletionCallback_Func([inout] mem_t user_data, | |
| [in] int32_t result); | |
| /** | |
| * This enumeration contains flags used to control how non-NULL callbacks are | |
| * scheduled by asynchronous methods. | |
| */ | |
| [assert_size(4)] | |
| enum PP_CompletionCallback_Flag { | |
| /** | |
| * By default any non-NULL callback will always invoked asynchronously, | |
| * on success or error, even if the operation could complete synchronously | |
| * without blocking. | |
| * | |
| * The method taking such callback will always return PP_OK_COMPLETIONPENDING. | |
| * The callback will be invoked on the same thread on which the method was | |
| * invoked. | |
| * | |
| * NOTE: If the method taking the callback is invoked on a background | |
| * thread that has no valid PPB_MessageLoop resource attached, the system has | |
| * no way to run the callback on the correct thread. In this case, a log | |
| * message will be emitted and the plugin will be made to crash. | |
| */ | |
| PP_COMPLETIONCALLBACK_FLAG_NONE = 0 << 0, | |
| /** | |
| * This flag allows any method taking such callback to complete synchronously | |
| * and not call the callback if the operation would not block. This is useful | |
| * when performance is an issue, and the operation bandwidth should not be | |
| * limited to the processing speed of the message loop. | |
| * | |
| * On synchronous method completion, the completion result will be returned | |
| * by the method itself. Otherwise, the method will return | |
| * PP_OK_COMPLETIONPENDING, and the callback will be invoked asynchronously on | |
| * the same thread on which the method was invoked. If there is no valid | |
| * PPB_MessageLoop attached to that thread, and the callback would normally | |
| * run asynchronously, the invoked method will return | |
| * PP_ERROR_NO_MESSAGE_LOOP. | |
| */ | |
| PP_COMPLETIONCALLBACK_FLAG_OPTIONAL = 1 << 0 | |
| }; | |
| /** | |
| * <code>PP_CompletionCallback</code> is a common mechanism for supporting | |
| * potentially asynchronous calls in browser interfaces. Any method that takes a | |
| * <code>PP_CompletionCallback</code> can be used in one of three different | |
| * ways: | |
| * - Required: The callback will always be invoked asynchronously on the | |
| * thread where the associated PPB method was invoked. The method | |
| * will always return PP_OK_COMPLETIONPENDING when a required | |
| * callback, and the callback will be invoked later (barring | |
| * system or thread shutdown; see PPB_MessageLoop for details). | |
| * Required callbacks are the default. | |
| * <br /><br /> | |
| * NOTE: If you use a required callback on a background thread, | |
| * you must have created and attached a PPB_MessageLoop. | |
| * Otherwise, the system can not run your callback on that thread, | |
| * and will instead emit a log message and crash your plugin to | |
| * make the problem more obvious. | |
| * | |
| * - Optional: The callback may be invoked asynchronously, or the PPB method | |
| * may complete synchronously if it can do so without blocking. | |
| * If the method will complete asynchronously, it will return | |
| * PP_OK_COMPLETIONPENDING. Otherwise, it will complete | |
| * synchronously and return an appropriate code (see below for | |
| * more information on the return code). Optional callbacks are | |
| * generally more difficult to use correctly than Required | |
| * callbacks, but can provide better performance for some APIs | |
| * (especially APIs with buffered reads, such as PPB_URLLoader or | |
| * PPB_FileIO). | |
| * <br /><br /> | |
| * NOTE: If you use an optional callback on a background thread, | |
| * and you have not created and attached a PPB_MessageLoop, then | |
| * the method you invoke will fail without running and return | |
| * PP_ERROR_NO_MESSAGE_LOOP. | |
| * | |
| * - Blocking: In this case, the callback's function pointer is NULL, and the | |
| * invoked method must complete synchronously. The method will | |
| * run to completion and return an appropriate code when finished | |
| * (see below for more information). Blocking completion | |
| * callbacks are only supported on background threads. | |
| * <br /><br /> | |
| * <code>PP_BlockUntilComplete()</code> provides a convenient way | |
| * to specify blocking behavior. Refer to | |
| * <code>PP_BlockUntilComplete</code> for more information. | |
| * | |
| * When the callback is run asynchronously, the result parameter passed to | |
| * <code>func</code> is an int32_t that, if negative indicates an error code | |
| * whose meaning is specific to the calling method (refer to | |
| * <code>pp_error.h</code> for further information). A positive or 0 value is a | |
| * return result indicating success whose meaning depends on the calling method | |
| * (e.g. number of bytes read). | |
| */ | |
| [passByValue] struct PP_CompletionCallback { | |
| /** | |
| * This value is a callback function that will be called, or NULL if this is | |
| * a blocking completion callback. | |
| */ | |
| PP_CompletionCallback_Func func; | |
| /** | |
| * This value is a pointer to user data passed to a callback function. | |
| */ | |
| mem_t user_data; | |
| /** | |
| * Flags used to control how non-NULL callbacks are scheduled by | |
| * asynchronous methods. | |
| */ | |
| int32_t flags; | |
| }; | |
| #inline c | |
| #include <stdlib.h> | |
| /** | |
| * @addtogroup Functions | |
| * @{ | |
| */ | |
| /** | |
| * PP_MakeCompletionCallback() is used to create a | |
| * <code>PP_CompletionCallback</code>. | |
| * | |
| * <strong>Example, creating a Required callback:</strong> | |
| * | |
| * @code | |
| * struct PP_CompletionCallback cc = PP_MakeCompletionCallback(Foo, NULL); | |
| * @endcode | |
| * | |
| * <strong>Example, creating an Optional callback:</strong> | |
| * | |
| * @code | |
| * struct PP_CompletionCallback cc = PP_MakeCompletionCallback(Foo, NULL); | |
| * cc.flags = cc.flags | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL; | |
| * @endcode | |
| * | |
| * @param[in] func A <code>PP_CompletionCallback_Func</code> that will be | |
| * called. | |
| * @param[in] user_data A pointer to user data passed to your callback | |
| * function. This is optional and is typically used to help track state | |
| * when you may have multiple callbacks pending. | |
| * | |
| * @return A <code>PP_CompletionCallback</code> structure. | |
| */ | |
| PP_INLINE struct PP_CompletionCallback PP_MakeCompletionCallback( | |
| PP_CompletionCallback_Func func, | |
| void* user_data) { | |
| struct PP_CompletionCallback cc; | |
| cc.func = func; | |
| cc.user_data = user_data; | |
| cc.flags = PP_COMPLETIONCALLBACK_FLAG_NONE; | |
| return cc; | |
| } | |
| /** | |
| * PP_MakeOptionalCompletionCallback() is used to create a PP_CompletionCallback | |
| * with PP_COMPLETIONCALLBACK_FLAG_OPTIONAL set. | |
| * | |
| * @param[in] func A PP_CompletionCallback_Func to be called on completion. | |
| * @param[in] user_data A pointer to user data passed to be passed to the | |
| * callback function. This is optional and is typically used to help track state | |
| * in case of multiple pending callbacks. | |
| * | |
| * @return A PP_CompletionCallback structure. | |
| */ | |
| PP_INLINE struct PP_CompletionCallback PP_MakeOptionalCompletionCallback( | |
| PP_CompletionCallback_Func func, | |
| void* user_data) { | |
| struct PP_CompletionCallback cc = PP_MakeCompletionCallback(func, user_data); | |
| cc.flags = cc.flags | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL; | |
| return cc; | |
| } | |
| /** | |
| * @} | |
| */ | |
| /** | |
| * @addtogroup Functions | |
| * @{ | |
| */ | |
| /** | |
| * PP_RunCompletionCallback() is used to run a callback. It invokes | |
| * the callback function passing it user data specified on creation and | |
| * completion |result|. | |
| * | |
| * @param[in] cc A pointer to a <code>PP_CompletionCallback</code> that will be | |
| * run. | |
| * @param[in] result The result of the operation. Non-positive values correspond | |
| * to the error codes from pp_errors.h (excluding PP_OK_COMPLETIONPENDING). | |
| * Positive values indicate additional information such as bytes read. | |
| */ | |
| PP_INLINE void PP_RunCompletionCallback(struct PP_CompletionCallback* cc, | |
| int32_t result) { | |
| cc->func(cc->user_data, result); | |
| } | |
| /** | |
| * @} | |
| */ | |
| /** | |
| * @addtogroup Functions | |
| * @{ | |
| */ | |
| /** | |
| * PP_BlockUntilComplete() is used in place of an actual completion callback | |
| * to request blocking behavior. If specified, the calling thread will block | |
| * until the function completes. Blocking completion callbacks are only allowed | |
| * from background threads. | |
| * | |
| * @return A <code>PP_CompletionCallback</code> structure. | |
| */ | |
| PP_INLINE struct PP_CompletionCallback PP_BlockUntilComplete(void) { | |
| return PP_MakeCompletionCallback(NULL, NULL); | |
| } | |
| /** | |
| * PP_RunAndClearCompletionCallback() runs a callback and clears the reference | |
| * to that callback. | |
| * | |
| * This function is used when the null-ness of a completion callback is used as | |
| * a signal for whether a completion callback has been registered. In this | |
| * case, after the execution of the callback, it should be cleared. However, | |
| * this introduces a conflict if the completion callback wants to schedule more | |
| * work that involves the same completion callback again (for example, when | |
| * reading data from an URLLoader, one would typically queue up another read | |
| * callback). As a result, this function clears the pointer | |
| * before the provided callback is executed. | |
| */ | |
| PP_INLINE void PP_RunAndClearCompletionCallback( | |
| struct PP_CompletionCallback* cc, | |
| int32_t res) { | |
| struct PP_CompletionCallback temp = *cc; | |
| *cc = PP_BlockUntilComplete(); | |
| PP_RunCompletionCallback(&temp, res); | |
| } | |
| /** | |
| * @} | |
| */ | |
| #endinl | |