Chromium Code Reviews| Index: ppapi/cpp/completion_callback.h |
| =================================================================== |
| --- ppapi/cpp/completion_callback.h (revision 89886) |
| +++ ppapi/cpp/completion_callback.h (working copy) |
| @@ -6,6 +6,7 @@ |
| #define PPAPI_CPP_COMPLETION_CALLBACK_H_ |
| #include "ppapi/c/pp_completion_callback.h" |
| +#include "ppapi/c/pp_errors.h" |
| #include "ppapi/cpp/logging.h" |
| #include "ppapi/cpp/non_thread_safe_ref_count.h" |
| @@ -27,6 +28,14 @@ |
| cc_ = PP_MakeCompletionCallback(func, user_data); |
| } |
| + CompletionCallback(PP_CompletionCallback_Func func, void* user_data, |
| + int32_t flags) { |
| + cc_ = PP_MakeCompletionCallback(func, user_data); |
| + cc_.flags = flags; |
| + } |
| + |
| + 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 |
| @@ -36,8 +45,21 @@ |
| PP_RunCompletionCallback(&cc_, result); |
| } |
| + bool IsOptional() const { |
| + return (cc_.func == NULL || |
| + (cc_.flags & PP_COMPLETIONCALLBACK_FLAG_OPTIONAL) != 0); |
| + } |
| + |
| const PP_CompletionCallback& pp_completion_callback() const { return cc_; } |
| + int32_t flags() const { return cc_.flags; } |
| + int32_t MayForce(int32_t result) const { |
|
brettw
2011/06/21 22:56:41
Can you provide a comment for this? It's a bit har
polina
2011/06/21 23:40:01
Done.
|
| + if (result == PP_OK_COMPLETIONPENDING || IsOptional()) |
| + return result; |
| + Module::Get()->core()->CallOnMainThread(0, *this, result); |
| + return PP_OK_COMPLETIONPENDING; |
| + } |
| + |
| protected: |
| PP_CompletionCallback cc_; |
| }; |
| @@ -67,10 +89,10 @@ |
| // } |
| // |
| // void ProcessFile(const FileRef& file) { |
| -// CompletionCallback cc = factory_.NewCallback(&MyHandler::DidOpen); |
| +// CompletionCallback cc = factory_.NewRequiredCallback( |
| +// &MyHandler::DidOpen); |
| // int32_t rv = fio_.Open(file, PP_FileOpenFlag_Read, cc); |
| -// if (rv != PP_OK_COMPLETIONPENDING) |
| -// cc.Run(rv); |
| +// CHECK(rv == PP_OK_COMPLETIONPENDING); |
| // } |
| // |
| // private: |
| @@ -100,7 +122,8 @@ |
| // } |
| // |
| // void ReadMore() { |
| -// CompletionCallback cc = factory_.NewCallback(&MyHandler::DidRead); |
| +// CompletionCallback cc = |
| +// factory_.NewOptionalCallback(&MyHandler::DidRead); |
| // int32_t rv = fio_.Read(offset_, buf_, sizeof(buf_), |
| // cc.pp_completion_callback()); |
| // if (rv != PP_OK_COMPLETIONPENDING) |
| @@ -145,11 +168,17 @@ |
| return object_; |
| } |
| - // Allocates a new, single-use CompletionCallback. The CompletionCallback |
| - // must be run in order for the memory allocated by NewCallback to be freed. |
| - // 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 otherwise memory will be leaked. |
| + // 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 NewOptionalCallback(). |
| + // TODO(polina): update this comment when this is no longer true. |
| template <typename Method> |
| CompletionCallback NewCallback(Method method) { |
| @@ -157,6 +186,20 @@ |
| return NewCallbackHelper(Dispatcher0<Method>(method)); |
| } |
| + template <typename Method> |
| + CompletionCallback NewRequiredCallback(Method method) { |
| + CompletionCallback cc = NewCallback(method); |
| + cc.set_flags(cc.flags() & ~PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); |
| + return cc; |
| + } |
| + |
| + template <typename Method> |
| + CompletionCallback NewOptionalCallback(Method method) { |
| + CompletionCallback cc = NewCallback(method); |
| + cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); |
| + return cc; |
| + } |
| + |
| // A copy of "a" will be passed to "method" when the completion callback |
| // runs. |
| // |
| @@ -169,6 +212,20 @@ |
| return NewCallbackHelper(Dispatcher1<Method, A>(method, a)); |
| } |
| + template <typename Method, typename A> |
| + CompletionCallback NewRequiredCallback(Method method, const A& a) { |
| + CompletionCallback cc = NewCallback(method, a); |
| + cc.set_flags(cc.flags() & ~PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); |
| + return cc; |
| + } |
| + |
| + template <typename Method, typename A> |
| + CompletionCallback NewOptionalCallback(Method method, const A& a) { |
| + CompletionCallback cc = NewCallback(method, a); |
| + cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); |
| + return cc; |
| + } |
| + |
| // A copy of "a" and "b" will be passed to "method" when the completion |
| // callback runs. |
| // |
| @@ -181,6 +238,22 @@ |
| return NewCallbackHelper(Dispatcher2<Method, A, B>(method, a, b)); |
| } |
| + template <typename Method, typename A, typename B> |
| + CompletionCallback NewRequiredCallback(Method method, const A& a, |
| + const B& b) { |
| + CompletionCallback cc = NewCallback(method, a, b); |
| + cc.set_flags(cc.flags() & ~PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); |
| + return cc; |
| + } |
| + |
| + template <typename Method, typename A, typename B> |
| + CompletionCallback NewOptionalCallback(Method method, const A& a, |
| + const B& b) { |
| + CompletionCallback cc = NewCallback(method, a, b); |
| + cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); |
| + return cc; |
| + } |
| + |
| private: |
| class BackPointer { |
| public: |