OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef PPAPI_PROXY_ENTER_PROXY_H_ | 5 #ifndef PPAPI_PROXY_ENTER_PROXY_H_ |
6 #define PPAPI_PROXY_ENTER_PROXY_H_ | 6 #define PPAPI_PROXY_ENTER_PROXY_H_ |
7 | 7 |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "ppapi/cpp/completion_callback.h" |
9 #include "ppapi/proxy/host_dispatcher.h" | 10 #include "ppapi/proxy/host_dispatcher.h" |
10 #include "ppapi/proxy/plugin_dispatcher.h" | 11 #include "ppapi/proxy/plugin_dispatcher.h" |
11 #include "ppapi/proxy/plugin_resource_tracker.h" | 12 #include "ppapi/proxy/plugin_resource_tracker.h" |
12 #include "ppapi/thunk/enter.h" | 13 #include "ppapi/thunk/enter.h" |
13 | 14 |
14 namespace pp { | 15 namespace pp { |
15 namespace proxy { | 16 namespace proxy { |
16 | 17 |
17 // Wrapper around EnterResourceNoLock that takes a host resource. This is used | 18 // Wrapper around EnterResourceNoLock that takes a host resource. This is used |
18 // when handling messages in the plugin from the host and we need to convert to | 19 // when handling messages in the plugin from the host and we need to convert to |
(...skipping 26 matching lines...) Expand all Loading... |
45 : ::ppapi::thunk::EnterResourceNoLock<ResourceT>( | 46 : ::ppapi::thunk::EnterResourceNoLock<ResourceT>( |
46 host_resource.host_resource(), false) { | 47 host_resource.host_resource(), false) { |
47 // Validate that we're in the host rather than the plugin. Otherwise this | 48 // Validate that we're in the host rather than the plugin. Otherwise this |
48 // object will do the wrong thing. In the host, the instance should have | 49 // object will do the wrong thing. In the host, the instance should have |
49 // a corresponding host disptacher (assuming the resource is valid). | 50 // a corresponding host disptacher (assuming the resource is valid). |
50 DCHECK(this->failed() || | 51 DCHECK(this->failed() || |
51 HostDispatcher::GetForInstance(host_resource.instance())); | 52 HostDispatcher::GetForInstance(host_resource.instance())); |
52 } | 53 } |
53 }; | 54 }; |
54 | 55 |
| 56 // Enters a resource and forces a completion callback to be issued. |
| 57 // |
| 58 // This is used when implementing the host (renderer) side of a resource |
| 59 // function that issues a completion callback. In all cases, we need to issue |
| 60 // the callback to avoid hanging the plugin. |
| 61 // |
| 62 // This class automatically constructs a callback with the given factory |
| 63 // calling the given method. The method will generally be the one that sends |
| 64 // the message to trigger the completion callback in the plugin process. |
| 65 // |
| 66 // It will automatically issue the callback with PP_ERROR_NOINTERFACE if the |
| 67 // host resource is invalid (i.e. failed() is set). In all other cases you |
| 68 // should call SetResult(), which will issue the callback immediately if the |
| 69 // result value isn't PP_OK_COMPLETIONPENDING. In the "completion pending" |
| 70 // case, it's assumed the function the proxy is calling will take responsibility |
| 71 // of executing the callback (returned by callback()). |
| 72 // |
| 73 // Example: |
| 74 // EnterHostFromHostResourceForceCallback<PPB_Foo_API> enter( |
| 75 // resource, callback_factory_, &MyClass::SendResult, resource); |
| 76 // if (enter.failed()) |
| 77 // return; // SendResult automatically called with PP_ERROR_BADRESOURCE. |
| 78 // enter.SetResult(enter.object()->DoFoo(enter.callback())); |
| 79 // |
| 80 // Where DoFoo's signature looks like this: |
| 81 // int32_t DoFoo(PP_CompletionCallback callback); |
| 82 // And SendResult's implementation looks like this: |
| 83 // void MyClass::SendResult(int32_t result, const HostResource& res) { |
| 84 // Send(new FooMsg_FooComplete(..., result, res)); |
| 85 // } |
| 86 template<typename ResourceT> |
| 87 class EnterHostFromHostResourceForceCallback |
| 88 : public EnterHostFromHostResource<ResourceT> { |
| 89 public: |
| 90 // For callbacks that take no parameters except the "int32_t result". Most |
| 91 // implementations will use the 1-extra-argument constructor below. |
| 92 template<class CallbackFactory, typename Method> |
| 93 EnterHostFromHostResourceForceCallback(const HostResource& host_resource, |
| 94 CallbackFactory& factory, |
| 95 Method method) |
| 96 : EnterHostFromHostResource<ResourceT>(host_resource), |
| 97 needs_running_(true), |
| 98 callback_(factory.NewOptionalCallback(method)) { |
| 99 if (this->failed()) |
| 100 RunCallback(PP_ERROR_BADRESOURCE); |
| 101 } |
| 102 |
| 103 // For callbacks that take an extra parameter as a closure. |
| 104 template<class CallbackFactory, typename Method, typename A> |
| 105 EnterHostFromHostResourceForceCallback(const HostResource& host_resource, |
| 106 CallbackFactory& factory, |
| 107 Method method, |
| 108 const A& a) |
| 109 : EnterHostFromHostResource<ResourceT>(host_resource), |
| 110 needs_running_(true), |
| 111 callback_(factory.NewOptionalCallback(method, a)) { |
| 112 if (this->failed()) |
| 113 RunCallback(PP_ERROR_BADRESOURCE); |
| 114 } |
| 115 |
| 116 ~EnterHostFromHostResourceForceCallback() { |
| 117 if (needs_running_) { |
| 118 NOTREACHED() << "Should always call SetResult except in the " |
| 119 "initialization failed case."; |
| 120 RunCallback(PP_ERROR_FAILED); |
| 121 } |
| 122 } |
| 123 |
| 124 void SetResult(int32_t result) { |
| 125 DCHECK(needs_running_) << "Don't call SetResult when there already is one."; |
| 126 if (result != PP_OK_COMPLETIONPENDING) |
| 127 callback_.Run(result); |
| 128 } |
| 129 |
| 130 PP_CompletionCallback callback() { |
| 131 return callback_.pp_completion_callback(); |
| 132 } |
| 133 |
| 134 private: |
| 135 void RunCallback(int32_t result) { |
| 136 DCHECK(needs_running_); |
| 137 needs_running_ = false; |
| 138 callback_.Run(result); |
| 139 } |
| 140 |
| 141 bool needs_running_; |
| 142 pp::CompletionCallback callback_; |
| 143 }; |
| 144 |
55 } // namespace proxy | 145 } // namespace proxy |
56 } // namespace pp | 146 } // namespace pp |
57 | 147 |
58 #endif // PPAPI_PROXY_ENTER_PROXY_H_ | 148 #endif // PPAPI_PROXY_ENTER_PROXY_H_ |
OLD | NEW |