Chromium Code Reviews| Index: ppapi/proxy/enter_proxy.h |
| =================================================================== |
| --- ppapi/proxy/enter_proxy.h (revision 94913) |
| +++ ppapi/proxy/enter_proxy.h (working copy) |
| @@ -6,6 +6,7 @@ |
| #define PPAPI_PROXY_ENTER_PROXY_H_ |
| #include "base/logging.h" |
| +#include "ppapi/cpp/completion_callback.h" |
| #include "ppapi/proxy/host_dispatcher.h" |
| #include "ppapi/proxy/plugin_dispatcher.h" |
| #include "ppapi/proxy/plugin_resource_tracker.h" |
| @@ -52,6 +53,95 @@ |
| } |
| }; |
| +// Enters a resource and forces a completion callback to be issued. |
| +// |
| +// This is used when implementing the host (renderer) side of a resource |
| +// function that issues a completion callback. In all cases, we need to issue |
| +// the callback to avoid hanging the plugin. |
| +// |
| +// This class automatically constructs a callback with the given factory |
| +// calling the given method. The method will generally be the one that sends |
| +// the message to trigger the completion callback in the plugin process. |
| +// |
| +// It will automatically issue the callback with PP_ERROR_NOINTERFACE if the |
| +// host resource is invalid (i.e. failed() is set). In all other cases you |
| +// should call SetResult(), which will issue the callback immediately if the |
| +// result value isn't PP_OK_COMPLETIONPENDING. In the "completion pending" |
| +// case, it's assumed the function the proxy is calling will take responsibility |
| +// of executing the callback (returned by callback()). |
| +// |
| +// Example: |
| +// EnterHostFromHostResourceForceCallback<PPB_Foo_API> enter( |
| +// resource, callback_factory_, &MyClass::SendResult, resource); |
| +// if (enter.failed()) |
| +// return; // SendResult automatically called with PP_ERROR_BADRESOURCE. |
| +// enter.SetResult(enter.object()->DoFoo(enter.callback())); |
| +// |
| +// Where DoFoo's signature looks like this: |
| +// int32_t DoFoo(PP_CompletionCallback callback); |
| +// And SendResult's implementation looks like this: |
| +// void MyClass::SendResult(int32_t result, const HostResource& res) { |
| +// Send(new FooMsg_FooComplete(..., result, res)); |
| +// } |
| +template<typename ResourceT> |
| +class EnterHostFromHostResourceForceCallback |
| + : public EnterHostFromHostResource<ResourceT> { |
| + public: |
| + // For callbacks that take no parameters except the "int32_t result". Most |
| + // implementations will use the 1-extra-argument constructor below. |
| + template<class CallbackFactory, typename Method> |
| + EnterHostFromHostResourceForceCallback(const HostResource& host_resource, |
| + CallbackFactory& factory, |
| + Method method) |
| + : EnterHostFromHostResource<ResourceT>(host_resource), |
| + needs_running_(true), |
| + callback_(factory.NewOptionalCallback(method)) { |
| + if (this->failed()) |
| + RunCallback(PP_ERROR_BADRESOURCE); |
| + } |
| + |
| + // For callbacks that take an extra parameter as a closure. |
| + template<class CallbackFactory, typename Method, typename A> |
| + EnterHostFromHostResourceForceCallback(const HostResource& host_resource, |
| + CallbackFactory& factory, |
| + Method method, |
| + A a) |
|
cpu_(ooo_6.6-7.5)
2011/08/03 00:57:21
A or A&, I mean do we expect a copy? or is it alwa
brettw
2011/08/03 17:36:29
Good point, this should be const& to match the Com
|
| + : EnterHostFromHostResource<ResourceT>(host_resource), |
| + needs_running_(true), |
| + callback_(factory.NewOptionalCallback(method, a)) { |
| + if (this->failed()) |
| + RunCallback(PP_ERROR_BADRESOURCE); |
| + } |
| + |
| + ~EnterHostFromHostResourceForceCallback() { |
| + if (needs_running_) { |
| + NOTREACHED() << "Should always call SetResult except in the " |
| + "initialization failed case."; |
| + RunCallback(PP_ERROR_FAILED); |
| + } |
| + } |
| + |
| + void SetResult(int32_t result) { |
| + DCHECK(needs_running_) << "Don't call SetResult when there already is one."; |
| + if (result != PP_OK_COMPLETIONPENDING) |
| + callback_.Run(result); |
| + } |
| + |
| + PP_CompletionCallback callback() { |
| + return callback_.pp_completion_callback(); |
| + } |
| + |
| + private: |
| + void RunCallback(int32_t result) { |
| + DCHECK(needs_running_); |
| + needs_running_ = false; |
| + callback_.Run(result); |
| + } |
| + |
| + bool needs_running_; |
| + pp::CompletionCallback callback_; |
| +}; |
| + |
| } // namespace proxy |
| } // namespace pp |