// 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 "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_errors.h" #include "ppapi/cpp/extensions/ext_output_traits.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_; }; namespace internal { /// The base class of [Ext]CompletionCallbackWithOutput. /// /// The template parameter Traits determines the storage type /// (OutputStorageType), the output parameter type used by the browser /// (APIArgType), and how to map OutputStorageType to APIArgType. template <typename T, typename Traits> class CompletionCallbackWithOutputBase : public CompletionCallback { public: typedef typename Traits::StorageType OutputStorageType; typedef typename Traits::APIArgType APIArgType; typedef Traits TraitsType; explicit CompletionCallbackWithOutputBase(OutputStorageType* output) : CompletionCallback(), output_(output) { } CompletionCallbackWithOutputBase(PP_CompletionCallback_Func func, void* user_data, OutputStorageType* output) : CompletionCallback(func, user_data), output_(output) { } CompletionCallbackWithOutputBase(PP_CompletionCallback_Func func, void* user_data, int32_t flags, OutputStorageType* output) : CompletionCallback(func, user_data, flags), output_(output) { } APIArgType output() const { return Traits::StorageToAPIArg(*output_); } private: OutputStorageType* output_; }; } // namespace internal /// 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 internal::CompletionCallbackWithOutputBase< T, internal::CallbackOutputTraits<T> > { public: typedef internal::CompletionCallbackWithOutputBase< T, internal::CallbackOutputTraits<T> > BaseType; /// The default constructor will create a blocking /// <code>CompletionCallbackWithOutput</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. /// In the common case, <code>OutputStorageType</code> will be equal to the /// template parameter T (for example, /// <code>CompletionCallbackWithOutput<int></code> would obviously take an /// int*. However, resources are passed as PP_Resource, vars as PP_Var, and /// arrays as our special ArrayOutputAdapter object. /// <code>internal::CallbackOutputTraits</code> defines specializations for /// all of these cases. /// /// <strong>Note:</strong> Blocking completion callbacks are only allowed from /// background threads. explicit CompletionCallbackWithOutput( typename BaseType::OutputStorageType* output) : BaseType(output) { } /// A constructor for creating a <code>CompletionCallbackWithOutput</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, typename BaseType::OutputStorageType* output) : BaseType(func, user_data, output) { } /// A constructor for creating a <code>CompletionCallbackWithOutput</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, typename BaseType::OutputStorageType* output) : BaseType(func, user_data, flags, output) { } }; namespace ext { /// ExtCompletionCallbackWithOutput is similar to CompletionCallbackWithOutput, /// but used by APIs within the pp::ext namespace. Usually it is used with the /// CompletionCallbackFactory's NewExtCallbackWithOutput. template <typename T> class ExtCompletionCallbackWithOutput : public ::pp::internal::CompletionCallbackWithOutputBase< T, internal::ExtCallbackOutputTraits<T> > { public: typedef ::pp::internal::CompletionCallbackWithOutputBase< T, internal::ExtCallbackOutputTraits<T> > BaseType; /// The default constructor will create a blocking /// <code>ExtCompletionCallbackWithOutput</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. /// <code>OutputStorageType</code> is either /// <code>ext::internal::ArrayVarOutputAdapterWithStorage<U></code> (if the /// template parameter T is of the form std::vector<U>) or /// <code>ext::internal::VarOutputAdapterWithStorage<T></code> (otherwise). /// /// <strong>Note:</strong> Blocking completion callbacks are only allowed from /// background threads. explicit ExtCompletionCallbackWithOutput( typename BaseType::OutputStorageType* output) : BaseType(output) { } /// A constructor for creating an <code>ExtCompletionCallbackWithOutput</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. ExtCompletionCallbackWithOutput(PP_CompletionCallback_Func func, void* user_data, typename BaseType::OutputStorageType* output) : BaseType(func, user_data, output) { } /// A constructor for creating an <code>ExtCompletionCallbackWithOutput</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. ExtCompletionCallbackWithOutput(PP_CompletionCallback_Func func, void* user_data, int32_t flags, typename BaseType::OutputStorageType* output) : BaseType(func, user_data, flags, output) { } }; } // namespace ext /// 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_