OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/cpp/completion_callback.h" |
10 #include "ppapi/proxy/host_dispatcher.h" | 10 #include "ppapi/proxy/host_dispatcher.h" |
11 #include "ppapi/proxy/plugin_dispatcher.h" | 11 #include "ppapi/proxy/plugin_dispatcher.h" |
(...skipping 26 matching lines...) Expand all Loading... |
38 DCHECK(this->failed() || | 38 DCHECK(this->failed() || |
39 PluginDispatcher::GetForInstance(host_resource.instance())); | 39 PluginDispatcher::GetForInstance(host_resource.instance())); |
40 } | 40 } |
41 }; | 41 }; |
42 | 42 |
43 template<typename ResourceT> | 43 template<typename ResourceT> |
44 class EnterHostFromHostResource | 44 class EnterHostFromHostResource |
45 : public thunk::EnterResourceNoLock<ResourceT> { | 45 : public thunk::EnterResourceNoLock<ResourceT> { |
46 public: | 46 public: |
47 explicit EnterHostFromHostResource(const HostResource& host_resource) | 47 explicit EnterHostFromHostResource(const HostResource& host_resource) |
48 : thunk::EnterResourceNoLock<ResourceT>( | 48 : thunk::EnterResourceNoLock<ResourceT>(host_resource.host_resource(), |
49 host_resource.host_resource(), false) { | 49 false) { |
50 // Validate that we're in the host rather than the plugin. Otherwise this | 50 // Validate that we're in the host rather than the plugin. Otherwise this |
51 // object will do the wrong thing. In the host, the instance should have | 51 // object will do the wrong thing. In the host, the instance should have |
52 // a corresponding host disptacher (assuming the resource is valid). | 52 // a corresponding host disptacher (assuming the resource is valid). |
| 53 DCHECK(this->failed() || |
| 54 HostDispatcher::GetForInstance(host_resource.instance())); |
| 55 } |
| 56 |
| 57 EnterHostFromHostResource(const HostResource& host_resource, |
| 58 const pp::CompletionCallback& callback) |
| 59 : thunk::EnterResourceNoLock<ResourceT>(host_resource.host_resource(), |
| 60 callback.pp_completion_callback(), |
| 61 false) { |
| 62 // Validate that we're in the host rather than the plugin. Otherwise this |
| 63 // object will do the wrong thing. In the host, the instance should have |
| 64 // a corresponding host disptacher (assuming the resource is valid). |
53 DCHECK(this->failed() || | 65 DCHECK(this->failed() || |
54 HostDispatcher::GetForInstance(host_resource.instance())); | 66 HostDispatcher::GetForInstance(host_resource.instance())); |
55 } | 67 } |
56 }; | 68 }; |
57 | 69 |
58 // Enters a resource and forces a completion callback to be issued. | 70 // Enters a resource and forces a completion callback to be issued. |
59 // | 71 // |
60 // This is used when implementing the host (renderer) side of a resource | 72 // This is used when implementing the host (renderer) side of a resource |
61 // function that issues a completion callback. In all cases, we need to issue | 73 // function that issues a completion callback. In all cases, we need to issue |
62 // the callback to avoid hanging the plugin. | 74 // the callback to avoid hanging the plugin. |
(...skipping 22 matching lines...) Expand all Loading... |
85 // void MyClass::SendResult(int32_t result, const HostResource& res) { | 97 // void MyClass::SendResult(int32_t result, const HostResource& res) { |
86 // Send(new FooMsg_FooComplete(..., result, res)); | 98 // Send(new FooMsg_FooComplete(..., result, res)); |
87 // } | 99 // } |
88 template<typename ResourceT> | 100 template<typename ResourceT> |
89 class EnterHostFromHostResourceForceCallback | 101 class EnterHostFromHostResourceForceCallback |
90 : public EnterHostFromHostResource<ResourceT> { | 102 : public EnterHostFromHostResource<ResourceT> { |
91 public: | 103 public: |
92 EnterHostFromHostResourceForceCallback( | 104 EnterHostFromHostResourceForceCallback( |
93 const HostResource& host_resource, | 105 const HostResource& host_resource, |
94 const pp::CompletionCallback& callback) | 106 const pp::CompletionCallback& callback) |
95 : EnterHostFromHostResource<ResourceT>(host_resource), | 107 : EnterHostFromHostResource<ResourceT>(host_resource, callback), |
96 needs_running_(true), | 108 needs_running_(true) { |
97 callback_(callback) { | |
98 } | 109 } |
99 | 110 |
100 // For callbacks that take no parameters except the "int32_t result". Most | 111 // For callbacks that take no parameters except the "int32_t result". Most |
101 // implementations will use the 1-extra-argument constructor below. | 112 // implementations will use the 1-extra-argument constructor below. |
102 template<class CallbackFactory, typename Method> | 113 template<class CallbackFactory, typename Method> |
103 EnterHostFromHostResourceForceCallback( | 114 EnterHostFromHostResourceForceCallback( |
104 const HostResource& host_resource, | 115 const HostResource& host_resource, |
105 CallbackFactory& factory, | 116 CallbackFactory& factory, |
106 Method method) | 117 Method method) |
107 : EnterHostFromHostResource<ResourceT>(host_resource), | 118 : EnterHostFromHostResource<ResourceT>(host_resource, |
108 needs_running_(true), | 119 factory.NewOptionalCallback(method)), |
109 callback_(factory.NewOptionalCallback(method)) { | 120 needs_running_(true) { |
110 if (this->failed()) | 121 if (this->failed()) |
111 RunCallback(PP_ERROR_BADRESOURCE); | 122 RunCallback(PP_ERROR_BADRESOURCE); |
112 } | 123 } |
113 | 124 |
114 // For callbacks that take an extra parameter as a closure. | 125 // For callbacks that take an extra parameter as a closure. |
115 template<class CallbackFactory, typename Method, typename A> | 126 template<class CallbackFactory, typename Method, typename A> |
116 EnterHostFromHostResourceForceCallback( | 127 EnterHostFromHostResourceForceCallback( |
117 const HostResource& host_resource, | 128 const HostResource& host_resource, |
118 CallbackFactory& factory, | 129 CallbackFactory& factory, |
119 Method method, | 130 Method method, |
120 const A& a) | 131 const A& a) |
121 : EnterHostFromHostResource<ResourceT>(host_resource), | 132 : EnterHostFromHostResource<ResourceT>(host_resource, |
122 needs_running_(true), | 133 factory.NewOptionalCallback(method, a)), |
123 callback_(factory.NewOptionalCallback(method, a)) { | 134 needs_running_(true) { |
124 if (this->failed()) | 135 if (this->failed()) |
125 RunCallback(PP_ERROR_BADRESOURCE); | 136 RunCallback(PP_ERROR_BADRESOURCE); |
126 } | 137 } |
127 | 138 |
128 // For callbacks that take two extra parameters as a closure. | 139 // For callbacks that take two extra parameters as a closure. |
129 template<class CallbackFactory, typename Method, typename A, typename B> | 140 template<class CallbackFactory, typename Method, typename A, typename B> |
130 EnterHostFromHostResourceForceCallback( | 141 EnterHostFromHostResourceForceCallback( |
131 const HostResource& host_resource, | 142 const HostResource& host_resource, |
132 CallbackFactory& factory, | 143 CallbackFactory& factory, |
133 Method method, | 144 Method method, |
134 const A& a, | 145 const A& a, |
135 const B& b) | 146 const B& b) |
136 : EnterHostFromHostResource<ResourceT>(host_resource), | 147 : EnterHostFromHostResource<ResourceT>(host_resource, |
137 needs_running_(true), | 148 factory.NewOptionalCallback(method, a, b)), |
138 callback_(factory.NewOptionalCallback(method, a, b)) { | 149 needs_running_(true) { |
139 if (this->failed()) | 150 if (this->failed()) |
140 RunCallback(PP_ERROR_BADRESOURCE); | 151 RunCallback(PP_ERROR_BADRESOURCE); |
141 } | 152 } |
142 | 153 |
143 ~EnterHostFromHostResourceForceCallback() { | 154 ~EnterHostFromHostResourceForceCallback() { |
144 if (needs_running_) { | 155 if (needs_running_) { |
145 NOTREACHED() << "Should always call SetResult except in the " | 156 NOTREACHED() << "Should always call SetResult except in the " |
146 "initialization failed case."; | 157 "initialization failed case."; |
147 RunCallback(PP_ERROR_FAILED); | 158 RunCallback(PP_ERROR_FAILED); |
148 } | 159 } |
149 } | 160 } |
150 | 161 |
151 void SetResult(int32_t result) { | 162 void SetResult(int32_t result) { |
152 DCHECK(needs_running_) << "Don't call SetResult when there already is one."; | 163 DCHECK(needs_running_) << "Don't call SetResult when there already is one."; |
| 164 if (result != PP_OK_COMPLETIONPENDING) |
| 165 RunCallback(result); |
153 needs_running_ = false; | 166 needs_running_ = false; |
154 if (result != PP_OK_COMPLETIONPENDING) | 167 // Either we already ran the callback, or it will be run asynchronously. We |
155 callback_.Run(result); | 168 // clear the callback so it isn't accidentally run again (and because |
156 } | 169 // EnterBase checks that the callback has been cleared). |
157 | 170 this->ClearCallback(); |
158 PP_CompletionCallback callback() { | |
159 return callback_.pp_completion_callback(); | |
160 } | 171 } |
161 | 172 |
162 private: | 173 private: |
163 void RunCallback(int32_t result) { | 174 void RunCallback(int32_t result) { |
164 DCHECK(needs_running_); | 175 DCHECK(needs_running_); |
165 needs_running_ = false; | 176 needs_running_ = false; |
166 callback_.Run(result); | 177 this->callback()->Run(result); |
| 178 this->ClearCallback(); |
167 } | 179 } |
168 | 180 |
169 bool needs_running_; | 181 bool needs_running_; |
170 pp::CompletionCallback callback_; | |
171 }; | 182 }; |
172 | 183 |
173 } // namespace proxy | 184 } // namespace proxy |
174 } // namespace ppapi | 185 } // namespace ppapi |
175 | 186 |
176 #endif // PPAPI_PROXY_ENTER_PROXY_H_ | 187 #endif // PPAPI_PROXY_ENTER_PROXY_H_ |
OLD | NEW |