/* 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 }; /** * PP_CompletionCallback is a common mechanism for supporting * potentially asynchronous calls in browser interfaces. Any method that takes a * PP_CompletionCallback 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. * * 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). * * 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. * * PP_BlockUntilComplete() provides a convenient way * to specify blocking behavior. Refer to * PP_BlockUntilComplete for more information. * * When the callback is run asynchronously, the result parameter passed to * func is an int32_t that, if negative indicates an error code * whose meaning is specific to the calling method (refer to * pp_error.h 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 /** * @addtogroup Functions * @{ */ /** * PP_MakeCompletionCallback() is used to create a * PP_CompletionCallback. * * Example, creating a Required callback: * * * struct PP_CompletionCallback cc = PP_MakeCompletionCallback(Foo, NULL); * * * Example, creating an Optional callback: * * * struct PP_CompletionCallback cc = PP_MakeCompletionCallback(Foo, NULL); * cc.flags = cc.flags | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL; * * * @param[in] func A PP_CompletionCallback_Func 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 PP_CompletionCallback 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 PP_CompletionCallback 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 PP_CompletionCallback 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