summaryrefslogtreecommitdiffstats
path: root/ppapi/cpp
diff options
context:
space:
mode:
authorjond@google.com <jond@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-22 19:41:00 +0000
committerjond@google.com <jond@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-22 19:41:00 +0000
commit3a9bcbf8625df86ec726b64036b39595625978c9 (patch)
treece2bf584dc8ee9ec8e14e4939eed510623193a04 /ppapi/cpp
parente2a246bcfab9cc56461e0486badc48c75f4029ad (diff)
downloadchromium_src-3a9bcbf8625df86ec726b64036b39595625978c9.zip
chromium_src-3a9bcbf8625df86ec726b64036b39595625978c9.tar.gz
chromium_src-3a9bcbf8625df86ec726b64036b39595625978c9.tar.bz2
I think I need a rubber stamp LGTM from you.
Review URL: http://codereview.chromium.org/7565016 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@97713 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/cpp')
-rw-r--r--ppapi/cpp/completion_callback.h447
1 files changed, 322 insertions, 125 deletions
diff --git a/ppapi/cpp/completion_callback.h b/ppapi/cpp/completion_callback.h
index 49f8d8f..797fb83 100644
--- a/ppapi/cpp/completion_callback.h
+++ b/ppapi/cpp/completion_callback.h
@@ -10,62 +10,130 @@
#include "ppapi/cpp/logging.h"
#include "ppapi/cpp/non_thread_safe_ref_count.h"
+/// @file
+/// This file defines the API to create and run a callback.
namespace pp {
-// A CompletionCallback provides a wrapper around PP_CompletionCallback.
+/// This API enables you to implement and receive callbacks when
+/// Pepper operations complete asynchronously.
class CompletionCallback {
public:
- // The default constructor will create a 'blocking' CompletionCallback
- // that may be passed to a method to indicate that the calling thread should
- // be blocked until the asynchronous operation corresponding to the method
- // completes.
+ /// 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.
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; }
- // Call this method to explicitly run the CompletionCallback. Normally, the
- // system runs a CompletionCallback after an asynchronous operation
- // completes, but programs may wish to run the CompletionCallback manually
- // in order to reuse the same code paths.
+ /// 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);
}
+ /// 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 main thread of Pepper execution.
+ ///
+ /// @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; }
- // Use this when implementing functions taking callbacks.
- // If the callback is required and |result| indicates that it has not
- // been scheduled, it will be forced on the main thread.
- //
- // EXAMPLE USAGE:
- //
- // 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);
- // }
- //
+ /// 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;
@@ -77,130 +145,170 @@ class CompletionCallback {
PP_CompletionCallback cc_;
};
-// Create a 'blocking' CompletionCallback.
+/// 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.
CompletionCallback BlockUntilComplete();
-// CompletionCallbackFactory<T> may be used to create CompletionCallback
-// objects that are bound to member functions.
-//
-// If a factory is destroyed, then any pending callbacks will be cancelled
-// preventing any bound member functions from being called. The CancelAll
-// method allows pending callbacks to be cancelled without destroying the
-// factory.
-//
-// NOTE: by default, CompletionCallbackFactory<T> isn't thread safe, but you can
-// make it more thread-friendly by passing a thread-safe refcounting class as
-// the second template element. However, it only guarantees safety for
-// *creating* a callback from another thread, the callback itself needs to
-// execute on the same thread as the thread that creates/destroys the factory.
-// With this restriction, it is safe to create the CompletionCallbackFactory on
-// the main thread, create callbacks from any thread and pass them to
-// CallOnMainThread.
-//
-// EXAMPLE USAGE:
-//
-// class MyHandler {
-// public:
-// MyHandler() : factory_(this), offset_(0) {
-// }
-//
-// void ProcessFile(const FileRef& file) {
-// CompletionCallback cc = factory_.NewRequiredCallback(
-// &MyHandler::DidOpen);
-// int32_t rv = fio_.Open(file, PP_FileOpenFlag_Read, cc);
-// CHECK(rv == PP_OK_COMPLETIONPENDING);
-// }
-//
-// private:
-// CompletionCallback NewCallback() {
-// return factory_.NewCallback(&MyHandler::DidCompleteIO);
-// }
-//
-// void DidOpen(int32_t result) {
-// if (result == PP_OK) {
-// // The file is open, and we can begin reading.
-// offset_ = 0;
-// ReadMore();
-// } else {
-// // Failed to open the file with error given by 'result'.
-// }
-// }
-//
-// void DidRead(int32_t result) {
-// if (result > 0) {
-// // buf_ now contains 'result' number of bytes from the file.
-// ProcessBytes(buf_, result);
-// offset_ += result;
-// ReadMore();
-// } else {
-// // Done reading (possibly with an error given by 'result').
-// }
-// }
-//
-// void ReadMore() {
-// CompletionCallback cc =
-// factory_.NewOptionalCallback(&MyHandler::DidRead);
-// int32_t rv = fio_.Read(offset_, buf_, sizeof(buf_),
-// cc.pp_completion_callback());
-// if (rv != PP_OK_COMPLETIONPENDING)
-// cc.Run(rv);
-// }
-//
-// void ProcessBytes(const char* bytes, int32_t length) {
-// // Do work ...
-// }
-//
-// pp::CompletionCallbackFactory<MyHandler> factory_;
-// pp::FileIO fio_;
-// char buf_[4096];
-// int64_t offset_;
-// };
-//
+/// CompletionCallbackFactory<T> may be used to create CompletionCallback
+/// objects that are bound to member functions.
+///
+/// If a factory is destroyed, then any pending callbacks will be cancelled
+/// preventing any bound member functions from being called. The CancelAll()
+/// method allows pending callbacks to be cancelled without destroying the
+/// factory.
+///
+/// <strong>Note: </strong><code>CompletionCallbackFactory<T></code> isn't
+/// thread safe, but you can make it more thread-friendly by passing a
+/// thread-safe refcounting class as the second template element. However, it
+/// only guarantees safety for creating a callback from another thread, the
+/// callback itself needs to execute on the same thread as the thread that
+/// creates/destroys the factory. With this restriction, it is safe to create
+/// the <code>CompletionCallbackFactory</code> on the main thread, create
+/// callbacks from any thread and pass them to CallOnMainThread().
+///
+/// <strong>Example: </strong>
+///
+/// @code
+///
+/// class MyHandler {
+/// public:
+/// MyHandler() : factory_(this), offset_(0) {
+/// }
+///
+/// void ProcessFile(const FileRef& file) {
+/// CompletionCallback cc = factory_.NewRequiredCallback(
+/// &MyHandler::DidOpen);
+/// int32_t rv = fio_.Open(file, PP_FileOpenFlag_Read, cc);
+/// CHECK(rv == PP_OK_COMPLETIONPENDING);
+/// }
+///
+/// private:
+/// CompletionCallback NewCallback() {
+/// return factory_.NewCallback(&MyHandler::DidCompleteIO);
+/// }
+///
+/// void DidOpen(int32_t result) {
+/// if (result == PP_OK) {
+/// // The file is open, and we can begin reading.
+/// offset_ = 0;
+/// ReadMore();
+/// } else {
+/// // Failed to open the file with error given by 'result'.
+/// }
+/// }
+///
+/// void DidRead(int32_t result) {
+/// if (result > 0) {
+/// // buf_ now contains 'result' number of bytes from the file.
+/// ProcessBytes(buf_, result);
+/// offset_ += result;
+/// ReadMore();
+/// } else {
+/// // Done reading (possibly with an error given by 'result').
+/// }
+/// }
+///
+/// void ReadMore() {
+/// CompletionCallback cc =
+/// factory_.NewOptionalCallback(&MyHandler::DidRead);
+/// int32_t rv = fio_.Read(offset_, buf_, sizeof(buf_),
+/// cc.pp_completion_callback());
+/// if (rv != PP_OK_COMPLETIONPENDING)
+/// cc.Run(rv);
+/// }
+///
+/// void ProcessBytes(const char* bytes, int32_t length) {
+/// // Do work ...
+/// }
+///
+/// pp::CompletionCallbackFactory<MyHandler> factory_;
+/// pp::FileIO fio_;
+/// char buf_[4096];
+/// int64_t offset_;
+/// };
+///
+/// @endcode
+///
template <typename T, typename RefCount = NonThreadSafeRefCount>
class CompletionCallbackFactory {
public:
+
+ /// This constructor creates a <code>CompletionCallbackFactory</code>
+ /// bound to an object. If the constructor is called without an argument,
+ /// the default value of <code>NULL</code> is used. The user then must call
+ /// Initialize() to initialize the object.
+ ///
+ /// param[in] object Optional parameter. An object whose member functions
+ /// are to be bound to CompletionCallbacks created by this
+ /// <code>CompletionCallbackFactory</code>. The default value of this
+ /// parameter is <code>NULL</code>.
explicit CompletionCallbackFactory(T* object = NULL)
: object_(object) {
InitBackPointer();
}
+ /// Destructor.
~CompletionCallbackFactory() {
ResetBackPointer();
}
- // Cancels all CompletionCallbacks allocated from this factory.
+ /// CancelAll() cancels all <code>CompletionCallbacks</code> allocated from
+ /// this factory.
void CancelAll() {
ResetBackPointer();
InitBackPointer();
}
-
+ /// Initialize() binds the <code>CallbackFactory</code> to a particular
+ /// object. Use this when the object is not available at
+ /// <code>CallbackFactory</code> creation, and the <code>NULL</code> default
+ /// is passed to the constructor. The object may only be initialized once,
+ /// either by the constructor, or by a call to Initialize().
+ ///
+ /// @param[in] object The object whose member functions are to be bound to
+ /// the <code>CompletionCallback</code> created by this
+ /// <code>CompletionCallbackFactory</code>.
void Initialize(T* object) {
PP_DCHECK(object);
PP_DCHECK(!object_); // May only initialize once!
object_ = object;
}
+ /// GetObject() returns the object that was passed at initialization to
+ /// Intialize().
+ ///
+ /// @return the object passed to the constructor or Intialize().
T* GetObject() {
return object_;
}
- // Methods for allocating new, single-use CompletionCallbacks.
- // The CompletionCallback must be run in order for the memory
- // allocated by the methods to be freed.
- // NewRequiredCallback() creates callbacks that will always run.
- // NewOptionalCallback() creates callbacks that might not run if the method
- // taking them can complete synchronously. Thus, if after passing the
- // CompletionCallback to a PPAPI method, the method does not return
- // PP_OK_COMPLETIONPENDING, then you should manually call the
- // CompletionCallback's Run method, or memory will be leaked.
- // NewCallback() is equivalent to NewRequiredCallback().
-
+ /// NewCallback allocates a new, single-use <code>CompletionCallback</code>.
+ /// The <code>CompletionCallback</code> must be run in order for the memory
+ /// allocated by the methods to be freed.
+ /// NewCallback() is equivalent to NewRequiredCallback() below.
+ ///
+ /// @param[in] method The method to be invoked upon completion of the
+ /// operation.
+ ///
+ /// @return A <code>CompletionCallback</code>.
template <typename Method>
CompletionCallback NewCallback(Method method) {
PP_DCHECK(object_);
return NewCallbackHelper(Dispatcher0<Method>(method));
}
+ /// NewRequiredCallback() allocates a new, single-use
+ /// <code>CompletionCallback</code> that will always run. The
+ /// <code>CompletionCallback</code> must be run in order for the memory
+ /// allocated by the methods to be freed.
+ ///
+ /// @param[in] method The method to be invoked upon completion of the
+ /// operation.
+ ///
+ /// @return A <code>CompletionCallback</code>.
template <typename Method>
CompletionCallback NewRequiredCallback(Method method) {
CompletionCallback cc = NewCallback(method);
@@ -208,6 +316,17 @@ class CompletionCallbackFactory {
return cc;
}
+ /// NewOptionalCallback() allocates a new, single-use
+ /// <code>CompletionCallback</code> that might not run if the method
+ /// taking it can complete synchronously. Thus, if after passing the
+ /// CompletionCallback to a Pepper method, the method does not return
+ /// PP_OK_COMPLETIONPENDING, then you should manually call the
+ /// CompletionCallback's Run method, or memory will be leaked.
+ ///
+ /// @param[in] method The method to be invoked upon completion of the
+ /// operation.
+ ///
+ /// @return A <code>CompletionCallback</code>.
template <typename Method>
CompletionCallback NewOptionalCallback(Method method) {
CompletionCallback cc = NewCallback(method);
@@ -215,18 +334,38 @@ class CompletionCallbackFactory {
return cc;
}
- // A copy of "a" will be passed to "method" when the completion callback
- // runs.
- //
- // Method should be of type:
- // void (T::*)(int32_t result, const A& a)
- //
+ /// NewCallback() allocates a new, single-use <code>CompletionCallback</code>.
+ /// The <code>CompletionCallback</code> must be run in order for the memory
+ /// allocated by the methods to be freed.
+ /// NewCallback() is equivalent to NewRequiredCallback() below.
+ ///
+ /// @param[in] method The method to be invoked upon completion of the
+ /// operation. Method should be of type:
+ /// <code>void (T::*)(int32_t result, const A& a)</code>
+ ///
+ /// @param[in] a Passed to <code>method</code> when the completion callback
+ /// runs.
+ ///
+ /// @return A <code>CompletionCallback</code>.
template <typename Method, typename A>
CompletionCallback NewCallback(Method method, const A& a) {
PP_DCHECK(object_);
return NewCallbackHelper(Dispatcher1<Method, A>(method, a));
}
+ /// NewRequiredCallback() allocates a new, single-use
+ /// <code>CompletionCallback</code> that will always run. The
+ /// <code>CompletionCallback</code> must be run in order for the memory
+ /// allocated by the methods to be freed.
+ ///
+ /// @param[in] method The method to be invoked upon completion of the
+ /// operation. Method should be of type:
+ /// <code>void (T::*)(int32_t result, const A& a)</code>
+ ///
+ /// @param[in] a Passed to <code>method</code> when the completion callback
+ /// runs.
+ ///
+ /// @return A <code>CompletionCallback</code>.
template <typename Method, typename A>
CompletionCallback NewRequiredCallback(Method method, const A& a) {
CompletionCallback cc = NewCallback(method, a);
@@ -234,6 +373,21 @@ class CompletionCallbackFactory {
return cc;
}
+ /// NewOptionalCallback() allocates a new, single-use
+ /// <code>CompletionCallback</code> that might not run if the method
+ /// taking it can complete synchronously. Thus, if after passing the
+ /// CompletionCallback to a Pepper method, the method does not return
+ /// PP_OK_COMPLETIONPENDING, then you should manually call the
+ /// CompletionCallback's Run method, or memory will be leaked.
+ ///
+ /// @param[in] method The method to be invoked upon completion of the
+ /// operation. Method should be of type:
+ /// <code>void (T::*)(int32_t result, const A& a)</code>
+ ///
+ /// @param[in] a Passed to <code>method</code> when the completion callback
+ /// runs.
+ ///
+ /// @return A <code>CompletionCallback</code>.
template <typename Method, typename A>
CompletionCallback NewOptionalCallback(Method method, const A& a) {
CompletionCallback cc = NewCallback(method, a);
@@ -241,18 +395,43 @@ class CompletionCallbackFactory {
return cc;
}
- // A copy of "a" and "b" will be passed to "method" when the completion
- // callback runs.
- //
- // Method should be of type:
- // void (T::*)(int32_t result, const A& a, const B& b)
- //
+ /// NewCallback() allocates a new, single-use
+ /// <code>CompletionCallback</code>.
+ /// The <code>CompletionCallback</code> must be run in order for the memory
+ /// allocated by the methods to be freed.
+ /// NewCallback() is equivalent to NewRequiredCallback() below.
+ ///
+ /// @param method The method taking the callback. Method should be of type:
+ /// <code>void (T::*)(int32_t result, const A& a, const B& b)</code>
+ ///
+ /// @param[in] a Passed to <code>method</code> when the completion callback
+ /// runs.
+ ///
+ /// @param[in] b Passed to <code>method</code> when the completion callback
+ /// runs.
+ ///
+ /// @return A <code>CompletionCallback</code>.
template <typename Method, typename A, typename B>
CompletionCallback NewCallback(Method method, const A& a, const B& b) {
PP_DCHECK(object_);
return NewCallbackHelper(Dispatcher2<Method, A, B>(method, a, b));
}
+ /// NewRequiredCallback() allocates a new, single-use
+ /// <code>CompletionCallback</code> that will always run. The
+ /// <code>CompletionCallback</code> must be run in order for the memory
+ /// allocated by the methods to be freed.
+ ///
+ /// @param method The method taking the callback. Method should be of type:
+ /// <code>void (T::*)(int32_t result, const A& a, const B& b)</code>
+ ///
+ /// @param[in] a Passed to <code>method</code> when the completion callback
+ /// runs.
+ ///
+ /// @param[in] b Passed to <code>method</code> when the completion callback
+ /// runs.
+ ///
+ /// @return A <code>CompletionCallback</code>.
template <typename Method, typename A, typename B>
CompletionCallback NewRequiredCallback(Method method, const A& a,
const B& b) {
@@ -261,6 +440,24 @@ class CompletionCallbackFactory {
return cc;
}
+ /// NewOptionalCallback() allocates a new, single-use
+ /// <code>CompletionCallback</code> that might not run if the method
+ /// taking it can complete synchronously. Thus, if after passing the
+ /// CompletionCallback to a Pepper method, the method does not return
+ /// PP_OK_COMPLETIONPENDING, then you should manually call the
+ /// CompletionCallback's Run method, or memory will be leaked.
+ ///
+ /// @param[in] method The method taking the callback. Method should be of
+ /// type:
+ /// <code>void (T::*)(int32_t result, const A& a, const B& b)</code>
+ ///
+ /// @param[in] a Passed to <code>method</code> when the completion callback
+ /// runs.
+ ///
+ /// @param[in] b Passed to <code>method</code> when the completion callback
+ /// runs.
+ ///
+ /// @return A <code>CompletionCallback</code>.
template <typename Method, typename A, typename B>
CompletionCallback NewOptionalCallback(Method method, const A& a,
const B& b) {