| Index: ppapi/proxy/enter_proxy.h
|
| ===================================================================
|
| --- ppapi/proxy/enter_proxy.h (revision 95737)
|
| +++ 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,96 @@
|
| }
|
| };
|
|
|
| +// 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,
|
| + const A& a)
|
| + : 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.";
|
| + needs_running_ = false;
|
| + 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
|
|
|
|
|