| // 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. | |
| #ifndef PPAPI_CPP_COMPLETION_CALLBACK_H_ | |
| #define PPAPI_CPP_COMPLETION_CALLBACK_H_ | |
| #include <stdint.h> | |
| #include "ppapi/c/pp_completion_callback.h" | |
| #include "ppapi/c/pp_errors.h" | |
| #include "ppapi/cpp/logging.h" | |
| #include "ppapi/cpp/module.h" | |
| #include "ppapi/cpp/output_traits.h" | |
| /// @file | |
| /// This file defines the API to create and run a callback. | |
| namespace pp { | |
| /// This API enables you to implement and receive callbacks when | |
| /// Pepper operations complete asynchronously. | |
| /// | |
| /// You can create these objects yourself, but it is most common to use the | |
| /// CompletionCallbackFactory to allow the callbacks to call class member | |
| /// functions. | |
| class CompletionCallback { | |
| public: | |
| /// The default constructor will create a blocking | |
| /// <code>CompletionCallback</code> that can be passed to a method to | |
| /// indicate that the calling thread should be blocked until the asynchronous | |
| /// operation corresponding to the method completes. | |
| /// | |
| /// <strong>Note:</strong> Blocking completion callbacks are only allowed from | |
| /// from background threads. | |
| CompletionCallback() { | |
| cc_ = PP_BlockUntilComplete(); | |
| } | |
| /// A constructor for creating a <code>CompletionCallback</code>. | |
| /// | |
| /// @param[in] func The function to be called on completion. | |
| /// @param[in] user_data The user data to be passed to the callback function. | |
| /// This is optional and is typically used to help track state in case of | |
| /// multiple pending callbacks. | |
| CompletionCallback(PP_CompletionCallback_Func func, void* user_data) { | |
| cc_ = PP_MakeCompletionCallback(func, user_data); | |
| } | |
| /// A constructor for creating a <code>CompletionCallback</code> with | |
| /// specified flags. | |
| /// | |
| /// @param[in] func The function to be called on completion. | |
| /// @param[in] user_data The user data to be passed to the callback function. | |
| /// This is optional and is typically used to help track state in case of | |
| /// multiple pending callbacks. | |
| /// @param[in] flags Bit field combination of | |
| /// <code>PP_CompletionCallback_Flag</code> flags used to control how | |
| /// non-NULL callbacks are scheduled by asynchronous methods. | |
| CompletionCallback(PP_CompletionCallback_Func func, void* user_data, | |
| int32_t flags) { | |
| cc_ = PP_MakeCompletionCallback(func, user_data); | |
| cc_.flags = flags; | |
| } | |
| /// The set_flags() function is used to set the flags used to control | |
| /// how non-NULL callbacks are scheduled by asynchronous methods. | |
| /// | |
| /// @param[in] flags Bit field combination of | |
| /// <code>PP_CompletionCallback_Flag</code> flags used to control how | |
| /// non-NULL callbacks are scheduled by asynchronous methods. | |
| void set_flags(int32_t flags) { cc_.flags = flags; } | |
| /// Run() is used to run the <code>CompletionCallback</code>. | |
| /// Normally, the system runs a <code>CompletionCallback</code> after an | |
| /// asynchronous operation completes, but programs may wish to run the | |
| /// <code>CompletionCallback</code> manually in order to reuse the same code | |
| /// paths. | |
| /// | |
| /// @param[in] result The result of the operation to be passed to the | |
| /// callback function. Non-positive values correspond to the error codes | |
| /// from <code>pp_errors.h</code> (excluding | |
| /// <code>PP_OK_COMPLETIONPENDING</code>). Positive values indicate | |
| /// additional information such as bytes read. | |
| void Run(int32_t result) { | |
| PP_DCHECK(cc_.func); | |
| PP_RunCompletionCallback(&cc_, result); | |
| } | |
| /// RunAndClear() is used to run the <code>CompletionCallback</code> and | |
| /// clear out the callback so that it cannot be run a second time. | |
| /// | |
| /// @param[in] result The result of the operation to be passed to the | |
| /// callback function. Non-positive values correspond to the error codes | |
| /// from <code>pp_errors.h</code> (excluding | |
| /// <code>PP_OK_COMPLETIONPENDING</code>). Positive values indicate | |
| /// additional information such as bytes read. | |
| void RunAndClear(int32_t result) { | |
| PP_DCHECK(cc_.func); | |
| PP_RunAndClearCompletionCallback(&cc_, result); | |
| } | |
| /// IsOptional() is used to determine the setting of the | |
| /// <code>PP_COMPLETIONCALLBACK_FLAG_OPTIONAL</code> flag. 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 where the PPB method was invoked. | |
| /// | |
| /// @return true if this callback is optional, otherwise false. | |
| bool IsOptional() const { | |
| return (cc_.func == NULL || | |
| (cc_.flags & PP_COMPLETIONCALLBACK_FLAG_OPTIONAL) != 0); | |
| } | |
| /// The pp_completion_callback() function returns the underlying | |
| /// <code>PP_CompletionCallback</code> | |
| /// | |
| /// @return A <code>PP_CompletionCallback</code>. | |
| const PP_CompletionCallback& pp_completion_callback() const { return cc_; } | |
| /// The flags() function returns flags used to control how non-NULL callbacks | |
| /// are scheduled by asynchronous methods. | |
| /// | |
| /// @return An int32_t containing a bit field combination of | |
| /// <code>PP_CompletionCallback_Flag</code> flags. | |
| int32_t flags() const { return cc_.flags; } | |
| /// MayForce() is used when implementing functions taking callbacks. | |
| /// If the callback is required and <code>result</code> indicates that it has | |
| /// not been scheduled, it will be forced on the main thread. | |
| /// | |
| /// <strong>Example:</strong> | |
| /// | |
| /// @code | |
| /// | |
| /// int32_t OpenURL(pp::URLLoader* loader, | |
| /// pp::URLRequestInfo* url_request_info, | |
| /// const CompletionCallback& cc) { | |
| /// if (loader == NULL || url_request_info == NULL) | |
| /// return cc.MayForce(PP_ERROR_BADRESOURCE); | |
| /// return loader->Open(*loader, *url_request_info, cc); | |
| /// } | |
| /// | |
| /// @endcode | |
| /// | |
| /// @param[in] result PP_OK_COMPLETIONPENDING or the result of the completed | |
| /// operation to be passed to the callback function. PP_OK_COMPLETIONPENDING | |
| /// indicates that the callback has already been scheduled. Other | |
| /// non-positive values correspond to error codes from | |
| /// <code>pp_errors.h</code>. Positive values indicate additional information | |
| /// such as bytes read. | |
| /// | |
| /// @return <code>PP_OK_COMPLETIONPENDING</code> if the callback has been | |
| /// forced, result parameter otherwise. | |
| int32_t MayForce(int32_t result) const { | |
| if (result == PP_OK_COMPLETIONPENDING || IsOptional()) | |
| return result; | |
| // FIXME(dmichael): Use pp::MessageLoop here once it's out of Dev. | |
| Module::Get()->core()->CallOnMainThread(0, *this, result); | |
| return PP_OK_COMPLETIONPENDING; | |
| } | |
| protected: | |
| PP_CompletionCallback cc_; | |
| }; | |
| /// A CompletionCallbackWithOutput defines a completion callback that | |
| /// additionally stores a pointer to some output data. Some C++ wrappers | |
| /// take a CompletionCallbackWithOutput when the browser is returning a | |
| /// bit of data as part of the function call. The "output" parameter | |
| /// stored in the CompletionCallbackWithOutput will receive the data from | |
| /// the browser. | |
| /// | |
| /// You can create this yourself, but it is most common to use with the | |
| /// CompletionCallbackFactory's NewCallbackWithOutput, which manages the | |
| /// storage for the output parameter for you and passes it as an argument | |
| /// to your callback function. | |
| /// | |
| /// Note that this class doesn't actually do anything with the output data, | |
| /// it just stores a pointer to it. C++ wrapper objects that accept a | |
| /// CompletionCallbackWithOutput will retrieve this pointer and pass it to | |
| /// the browser as the output parameter. | |
| template<typename T> | |
| class CompletionCallbackWithOutput : public CompletionCallback { | |
| public: | |
| /// The type that will actually be stored in the completion callback. In the | |
| /// common case, this will be equal to the template parameter (for example, | |
| /// CompletionCallbackWithOutput<int> would obviously take an int*. However, | |
| /// resources are passed as PP_Resource, vars as PP_Var, and arrays as our | |
| /// special ArrayOutputAdapter object. The CallbackOutputTraits defines | |
| /// specializations for all of these cases. | |
| typedef typename internal::CallbackOutputTraits<T>::StorageType | |
| OutputStorageType; | |
| typedef typename internal::CallbackOutputTraits<T>::APIArgType | |
| APIArgType; | |
| /// The default constructor will create a blocking | |
| /// <code>CompletionCallback</code> that references the given output | |
| /// data. | |
| /// | |
| /// @param[in] output A pointer to the data associated with the callback. The | |
| /// caller must ensure that this pointer outlives the completion callback. | |
| /// | |
| /// <strong>Note:</strong> Blocking completion callbacks are only allowed from | |
| /// from background threads. | |
| CompletionCallbackWithOutput(OutputStorageType* output) | |
| : CompletionCallback(), | |
| output_(output) { | |
| } | |
| /// A constructor for creating a <code>CompletionCallback</code> that | |
| /// references the given output data. | |
| /// | |
| /// @param[in] func The function to be called on completion. | |
| /// @param[in] user_data The user data to be passed to the callback function. | |
| /// This is optional and is typically used to help track state in case of | |
| /// multiple pending callbacks. | |
| /// @param[in] output A pointer to the data associated with the callback. The | |
| /// caller must ensure that this pointer outlives the completion callback. | |
| CompletionCallbackWithOutput(PP_CompletionCallback_Func func, | |
| void* user_data, | |
| OutputStorageType* output) | |
| : CompletionCallback(func, user_data), | |
| output_(output) { | |
| } | |
| /// A constructor for creating a <code>CompletionCallback</code> that | |
| /// references the given output data. | |
| /// | |
| /// @param[in] func The function to be called on completion. | |
| /// | |
| /// @param[in] user_data The user data to be passed to the callback function. | |
| /// This is optional and is typically used to help track state in case of | |
| /// multiple pending callbacks. | |
| /// | |
| /// @param[in] flags Bit field combination of | |
| /// <code>PP_CompletionCallback_Flag</code> flags used to control how | |
| /// non-NULL callbacks are scheduled by asynchronous methods. | |
| /// | |
| /// @param[in] output A pointer to the data associated with the callback. The | |
| /// caller must ensure that this pointer outlives the completion callback. | |
| CompletionCallbackWithOutput(PP_CompletionCallback_Func func, | |
| void* user_data, | |
| int32_t flags, | |
| OutputStorageType* output) | |
| : CompletionCallback(func, user_data, flags), | |
| output_(output) { | |
| } | |
| APIArgType output() const { | |
| return internal::CallbackOutputTraits<T>::StorageToAPIArg(*output_); | |
| } | |
| private: | |
| OutputStorageType* output_; | |
| }; | |
| /// 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>CompletionCallback</code> corresponding to a NULL callback. | |
| inline CompletionCallback BlockUntilComplete() { | |
| // Note: Explicitly inlined to avoid link errors when included into | |
| // ppapi_proxy and ppapi_cpp_objects. | |
| return CompletionCallback(); | |
| } | |
| } // namespace pp | |
| #endif // PPAPI_CPP_COMPLETION_CALLBACK_H_ |