Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(32)

Side by Side Diff: ppapi/thunk/enter.cc

Issue 2762513002: Remove keep-alive impulse IPCs from NaCl modules. (Closed)
Patch Set: Rebase Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ppapi/thunk/enter.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 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 #include "ppapi/thunk/enter.h" 5 #include "ppapi/thunk/enter.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/stringprintf.h" 10 #include "base/strings/stringprintf.h"
11 #include "base/synchronization/lock.h" 11 #include "base/synchronization/lock.h"
12 #include "ppapi/c/pp_errors.h"
13 #include "ppapi/shared_impl/ppapi_globals.h" 12 #include "ppapi/shared_impl/ppapi_globals.h"
14 #include "ppapi/shared_impl/tracked_callback.h" 13 #include "ppapi/shared_impl/tracked_callback.h"
15 #include "ppapi/thunk/ppb_instance_api.h" 14 #include "ppapi/thunk/ppb_instance_api.h"
16 #include "ppapi/thunk/resource_creation_api.h" 15 #include "ppapi/thunk/resource_creation_api.h"
17 16
18 namespace ppapi { 17 namespace ppapi {
19 namespace { 18 namespace {
20 19
21 bool IsMainThread() { 20 bool IsMainThread() {
22 return 21 return
23 PpapiGlobals::Get()->GetMainThreadMessageLoop()->BelongsToCurrentThread(); 22 PpapiGlobals::Get()->GetMainThreadMessageLoop()->BelongsToCurrentThread();
24 } 23 }
25 24
26 bool CurrentThreadHandlingBlockingMessage() { 25 bool CurrentThreadHandlingBlockingMessage() {
27 ppapi::MessageLoopShared* current = 26 ppapi::MessageLoopShared* current =
28 PpapiGlobals::Get()->GetCurrentMessageLoop(); 27 PpapiGlobals::Get()->GetCurrentMessageLoop();
29 return current && current->CurrentlyHandlingBlockingMessage(); 28 return current && current->CurrentlyHandlingBlockingMessage();
30 } 29 }
31 30
32 } // namespace 31 } // namespace
33 32
34 namespace thunk { 33 namespace thunk {
35 34
36 namespace subtle { 35 namespace subtle {
37 36
38 EnterBase::EnterBase() 37 EnterBase::EnterBase() {}
39 : resource_(NULL),
40 retval_(PP_OK) {
41 PpapiGlobals::Get()->MarkPluginIsActive();
42 }
43 38
44 EnterBase::EnterBase(PP_Resource resource) 39 EnterBase::EnterBase(PP_Resource resource) : resource_(GetResource(resource)) {}
45 : resource_(GetResource(resource)),
46 retval_(PP_OK) {
47 PpapiGlobals::Get()->MarkPluginIsActive();
48 }
49 40
50 EnterBase::EnterBase(PP_Instance instance, SingletonResourceID resource_id) 41 EnterBase::EnterBase(PP_Instance instance, SingletonResourceID resource_id)
51 : resource_(GetSingletonResource(instance, resource_id)), 42 : resource_(GetSingletonResource(instance, resource_id)) {
52 retval_(PP_OK) { 43 if (!resource_)
53 PpapiGlobals::Get()->MarkPluginIsActive(); 44 retval_ = PP_ERROR_BADARGUMENT;
54 } 45 }
55 46
56 EnterBase::EnterBase(PP_Resource resource, 47 EnterBase::EnterBase(PP_Resource resource,
57 const PP_CompletionCallback& callback) 48 const PP_CompletionCallback& callback)
58 : resource_(GetResource(resource)), 49 : EnterBase(resource) {
59 retval_(PP_OK) {
60 callback_ = new TrackedCallback(resource_, callback); 50 callback_ = new TrackedCallback(resource_, callback);
61 PpapiGlobals::Get()->MarkPluginIsActive();
62 } 51 }
63 52
64 EnterBase::EnterBase(PP_Instance instance, SingletonResourceID resource_id, 53 EnterBase::EnterBase(PP_Instance instance,
54 SingletonResourceID resource_id,
65 const PP_CompletionCallback& callback) 55 const PP_CompletionCallback& callback)
66 : resource_(GetSingletonResource(instance, resource_id)), 56 : EnterBase(instance, resource_id) {
67 retval_(PP_OK) {
68 if (!resource_)
69 retval_ = PP_ERROR_BADARGUMENT;
70 callback_ = new TrackedCallback(resource_, callback); 57 callback_ = new TrackedCallback(resource_, callback);
71 PpapiGlobals::Get()->MarkPluginIsActive();
72 } 58 }
73 59
74 EnterBase::~EnterBase() { 60 EnterBase::~EnterBase() {
75 // callback_ is cleared any time it is run, scheduled to be run, or once we 61 // callback_ is cleared any time it is run, scheduled to be run, or once we
76 // know it will be completed asynchronously. So by this point it should be 62 // know it will be completed asynchronously. So by this point it should be
77 // NULL. 63 // null.
78 DCHECK(!callback_.get()) 64 DCHECK(!callback_) << "|callback_| is not null. Did you forget to call "
79 << "|callback_| is not NULL. Did you forget to call " 65 "|EnterBase::SetResult| in the interface's thunk?";
80 "|EnterBase::SetResult| in the interface's thunk?";
81 } 66 }
82 67
83 int32_t EnterBase::SetResult(int32_t result) { 68 int32_t EnterBase::SetResult(int32_t result) {
84 if (!callback_.get()) { 69 if (!callback_) {
85 // It doesn't make sense to call SetResult if there is no callback. 70 // It doesn't make sense to call SetResult if there is no callback.
86 NOTREACHED(); 71 NOTREACHED();
87 retval_ = result; 72 retval_ = result;
88 return result; 73 return result;
89 } 74 }
90 if (result == PP_OK_COMPLETIONPENDING) { 75 if (result == PP_OK_COMPLETIONPENDING) {
91 retval_ = result; 76 retval_ = result;
92 if (callback_->is_blocking()) { 77 if (callback_->is_blocking()) {
93 DCHECK(!IsMainThread()); // We should have returned an error before this. 78 DCHECK(!IsMainThread()); // We should have returned an error before this.
94 retval_ = callback_->BlockUntilComplete(); 79 retval_ = callback_->BlockUntilComplete();
95 } else { 80 } else {
96 // The callback is not blocking and the operation will complete 81 // The callback is not blocking and the operation will complete
97 // asynchronously, so there's nothing to do. 82 // asynchronously, so there's nothing to do.
98 retval_ = result; 83 retval_ = result;
99 } 84 }
100 } else { 85 } else {
101 // The function completed synchronously. 86 // The function completed synchronously.
102 if (callback_->is_required()) { 87 if (callback_->is_required()) {
103 // This is a required callback, so we must issue it asynchronously. 88 // This is a required callback, so we must issue it asynchronously.
104 callback_->PostRun(result); 89 callback_->PostRun(result);
105 retval_ = PP_OK_COMPLETIONPENDING; 90 retval_ = PP_OK_COMPLETIONPENDING;
106 } else { 91 } else {
107 // The callback is blocking or optional, so all we need to do is mark 92 // The callback is blocking or optional, so all we need to do is mark
108 // the callback as completed so that it won't be issued later. 93 // the callback as completed so that it won't be issued later.
109 callback_->MarkAsCompleted(); 94 callback_->MarkAsCompleted();
110 retval_ = result; 95 retval_ = result;
111 } 96 }
112 } 97 }
113 callback_ = NULL; 98 callback_ = nullptr;
114 return retval_; 99 return retval_;
115 } 100 }
116 101
117 // static 102 // static
118 Resource* EnterBase::GetResource(PP_Resource resource) { 103 Resource* EnterBase::GetResource(PP_Resource resource) {
119 return PpapiGlobals::Get()->GetResourceTracker()->GetResource(resource); 104 return PpapiGlobals::Get()->GetResourceTracker()->GetResource(resource);
120 } 105 }
121 106
122 // static 107 // static
123 Resource* EnterBase::GetSingletonResource(PP_Instance instance, 108 Resource* EnterBase::GetSingletonResource(PP_Instance instance,
124 SingletonResourceID resource_id) { 109 SingletonResourceID resource_id) {
125 PPB_Instance_API* ppb_instance = 110 PPB_Instance_API* ppb_instance =
126 PpapiGlobals::Get()->GetInstanceAPI(instance); 111 PpapiGlobals::Get()->GetInstanceAPI(instance);
127 if (!ppb_instance) 112 if (!ppb_instance)
128 return NULL; 113 return nullptr;
129 114
130 return ppb_instance->GetSingletonResource(instance, resource_id); 115 return ppb_instance->GetSingletonResource(instance, resource_id);
131 } 116 }
132 117
133 void EnterBase::SetStateForCallbackError(bool report_error) { 118 void EnterBase::SetStateForCallbackError(bool report_error) {
134 if (PpapiGlobals::Get()->IsHostGlobals()) { 119 if (PpapiGlobals::Get()->IsHostGlobals()) {
135 // In-process plugins can't make PPAPI calls off the main thread. 120 // In-process plugins can't make PPAPI calls off the main thread.
136 CHECK(IsMainThread()); 121 CHECK(IsMainThread());
137 } 122 }
138 if (callback_.get()) { 123 if (callback_) {
139 if (callback_->is_blocking() && IsMainThread()) { 124 if (callback_->is_blocking() && IsMainThread()) {
140 // Blocking callbacks are never allowed on the main thread. 125 // Blocking callbacks are never allowed on the main thread.
141 callback_->MarkAsCompleted(); 126 callback_->MarkAsCompleted();
142 callback_ = NULL; 127 callback_ = nullptr;
143 retval_ = PP_ERROR_BLOCKS_MAIN_THREAD; 128 retval_ = PP_ERROR_BLOCKS_MAIN_THREAD;
144 if (report_error) { 129 if (report_error) {
145 std::string message( 130 std::string message(
146 "Blocking callbacks are not allowed on the main thread."); 131 "Blocking callbacks are not allowed on the main thread.");
147 PpapiGlobals::Get()->BroadcastLogWithSource(0, PP_LOGLEVEL_ERROR, 132 PpapiGlobals::Get()->BroadcastLogWithSource(0, PP_LOGLEVEL_ERROR,
148 std::string(), message); 133 std::string(), message);
149 } 134 }
150 } else if (callback_->is_blocking() && 135 } else if (callback_->is_blocking() &&
151 CurrentThreadHandlingBlockingMessage()) { 136 CurrentThreadHandlingBlockingMessage()) {
152 // Blocking callbacks are not allowed while handling a blocking message. 137 // Blocking callbacks are not allowed while handling a blocking message.
153 callback_->MarkAsCompleted(); 138 callback_->MarkAsCompleted();
154 callback_ = NULL; 139 callback_ = nullptr;
155 retval_ = PP_ERROR_WOULD_BLOCK_THREAD; 140 retval_ = PP_ERROR_WOULD_BLOCK_THREAD;
156 if (report_error) { 141 if (report_error) {
157 std::string message("Blocking callbacks are not allowed while handling " 142 std::string message("Blocking callbacks are not allowed while handling "
158 "a blocking message from JavaScript."); 143 "a blocking message from JavaScript.");
159 PpapiGlobals::Get()->BroadcastLogWithSource(0, PP_LOGLEVEL_ERROR, 144 PpapiGlobals::Get()->BroadcastLogWithSource(0, PP_LOGLEVEL_ERROR,
160 std::string(), message); 145 std::string(), message);
161 } 146 }
162 } else if (!IsMainThread() && 147 } else if (!IsMainThread() &&
163 callback_->has_null_target_loop() && 148 callback_->has_null_target_loop() &&
164 !callback_->is_blocking()) { 149 !callback_->is_blocking()) {
165 // On a non-main thread, there must be a valid target loop for non- 150 // On a non-main thread, there must be a valid target loop for non-
166 // blocking callbacks, or we will have no place to run them. 151 // blocking callbacks, or we will have no place to run them.
167 152
168 // If the callback is required, there's no nice way to tell the plugin. 153 // If the callback is required, there's no nice way to tell the plugin.
169 // We can't run their callback asynchronously without a message loop, and 154 // We can't run their callback asynchronously without a message loop, and
170 // the plugin won't expect any return code other than 155 // the plugin won't expect any return code other than
171 // PP_OK_COMPLETIONPENDING. So we crash to make the problem more obvious. 156 // PP_OK_COMPLETIONPENDING. So we crash to make the problem more obvious.
172 if (callback_->is_required()) { 157 if (callback_->is_required()) {
173 std::string message("Attempted to use a required callback, but there " 158 std::string message("Attempted to use a required callback, but there "
174 "is no attached message loop on which to run the " 159 "is no attached message loop on which to run the "
175 "callback."); 160 "callback.");
176 PpapiGlobals::Get()->BroadcastLogWithSource(0, PP_LOGLEVEL_ERROR, 161 PpapiGlobals::Get()->BroadcastLogWithSource(0, PP_LOGLEVEL_ERROR,
177 std::string(), message); 162 std::string(), message);
178 LOG(FATAL) << message; 163 LOG(FATAL) << message;
179 } 164 }
180 165
181 callback_->MarkAsCompleted(); 166 callback_->MarkAsCompleted();
182 callback_ = NULL; 167 callback_ = nullptr;
183 retval_ = PP_ERROR_NO_MESSAGE_LOOP; 168 retval_ = PP_ERROR_NO_MESSAGE_LOOP;
184 if (report_error) { 169 if (report_error) {
185 std::string message( 170 std::string message(
186 "The calling thread must have a message loop attached."); 171 "The calling thread must have a message loop attached.");
187 PpapiGlobals::Get()->BroadcastLogWithSource(0, PP_LOGLEVEL_ERROR, 172 PpapiGlobals::Get()->BroadcastLogWithSource(0, PP_LOGLEVEL_ERROR,
188 std::string(), message); 173 std::string(), message);
189 } 174 }
190 } 175 }
191 } 176 }
192 } 177 }
193 178
194 void EnterBase::ClearCallback() { 179 void EnterBase::ClearCallback() {
195 callback_ = NULL; 180 callback_ = nullptr;
196 } 181 }
197 182
198 void EnterBase::SetStateForResourceError(PP_Resource pp_resource, 183 void EnterBase::SetStateForResourceError(PP_Resource pp_resource,
199 Resource* resource_base, 184 Resource* resource_base,
200 void* object, 185 void* object,
201 bool report_error) { 186 bool report_error) {
202 // Check for callback errors. If we get any, SetStateForCallbackError will 187 // Check for callback errors. If we get any, SetStateForCallbackError will
203 // emit a log message. But we also want to check for resource errors. If there 188 // emit a log message. But we also want to check for resource errors. If there
204 // are both kinds of errors, we'll emit two log messages and return 189 // are both kinds of errors, we'll emit two log messages and return
205 // PP_ERROR_BADRESOURCE. 190 // PP_ERROR_BADRESOURCE.
206 SetStateForCallbackError(report_error); 191 SetStateForCallbackError(report_error);
207 192
208 if (object) 193 if (object)
209 return; // Everything worked. 194 return; // Everything worked.
210 195
211 if (callback_.get() && callback_->is_required()) { 196 if (callback_ && callback_->is_required()) {
212 callback_->PostRun(static_cast<int32_t>(PP_ERROR_BADRESOURCE)); 197 callback_->PostRun(static_cast<int32_t>(PP_ERROR_BADRESOURCE));
213 callback_ = NULL; 198 callback_ = nullptr;
214 retval_ = PP_OK_COMPLETIONPENDING; 199 retval_ = PP_OK_COMPLETIONPENDING;
215 } else { 200 } else {
216 if (callback_.get()) 201 if (callback_)
217 callback_->MarkAsCompleted(); 202 callback_->MarkAsCompleted();
218 callback_ = NULL; 203 callback_ = nullptr;
219 retval_ = PP_ERROR_BADRESOURCE; 204 retval_ = PP_ERROR_BADRESOURCE;
220 } 205 }
221 206
222 // We choose to silently ignore the error when the pp_resource is null 207 // We choose to silently ignore the error when the pp_resource is null
223 // because this is a pretty common case and we don't want to have lots 208 // because this is a pretty common case and we don't want to have lots
224 // of errors in the log. This should be an obvious case to debug. 209 // of errors in the log. This should be an obvious case to debug.
225 if (report_error && pp_resource) { 210 if (report_error && pp_resource) {
226 std::string message; 211 std::string message;
227 if (resource_base) { 212 if (resource_base) {
228 message = base::StringPrintf( 213 message = base::StringPrintf(
(...skipping 14 matching lines...) Expand all
243 bool report_error) { 228 bool report_error) {
244 // Check for callback errors. If we get any, SetStateForCallbackError will 229 // Check for callback errors. If we get any, SetStateForCallbackError will
245 // emit a log message. But we also want to check for instance errors. If there 230 // emit a log message. But we also want to check for instance errors. If there
246 // are both kinds of errors, we'll emit two log messages and return 231 // are both kinds of errors, we'll emit two log messages and return
247 // PP_ERROR_BADARGUMENT. 232 // PP_ERROR_BADARGUMENT.
248 SetStateForCallbackError(report_error); 233 SetStateForCallbackError(report_error);
249 234
250 if (object) 235 if (object)
251 return; // Everything worked. 236 return; // Everything worked.
252 237
253 if (callback_.get() && callback_->is_required()) { 238 if (callback_ && callback_->is_required()) {
254 callback_->PostRun(static_cast<int32_t>(PP_ERROR_BADARGUMENT)); 239 callback_->PostRun(static_cast<int32_t>(PP_ERROR_BADARGUMENT));
255 callback_ = NULL; 240 callback_ = nullptr;
256 retval_ = PP_OK_COMPLETIONPENDING; 241 retval_ = PP_OK_COMPLETIONPENDING;
257 } else { 242 } else {
258 if (callback_.get()) 243 if (callback_)
259 callback_->MarkAsCompleted(); 244 callback_->MarkAsCompleted();
260 callback_ = NULL; 245 callback_ = nullptr;
261 retval_ = PP_ERROR_BADARGUMENT; 246 retval_ = PP_ERROR_BADARGUMENT;
262 } 247 }
263 248
264 // We choose to silently ignore the error when the pp_instance is null as 249 // We choose to silently ignore the error when the pp_instance is null as
265 // for PP_Resources above. 250 // for PP_Resources above.
266 if (report_error && pp_instance) { 251 if (report_error && pp_instance) {
267 std::string message; 252 std::string message;
268 message = base::StringPrintf( 253 message = base::StringPrintf(
269 "0x%X is not a valid instance ID.", 254 "0x%X is not a valid instance ID.",
270 pp_instance); 255 pp_instance);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 : EnterBase(), 312 : EnterBase(),
328 functions_(PpapiGlobals::Get()->GetResourceCreationAPI(instance)) { 313 functions_(PpapiGlobals::Get()->GetResourceCreationAPI(instance)) {
329 SetStateForFunctionError(instance, functions_, true); 314 SetStateForFunctionError(instance, functions_, true);
330 } 315 }
331 316
332 EnterResourceCreationNoLock::~EnterResourceCreationNoLock() { 317 EnterResourceCreationNoLock::~EnterResourceCreationNoLock() {
333 } 318 }
334 319
335 } // namespace thunk 320 } // namespace thunk
336 } // namespace ppapi 321 } // namespace ppapi
OLDNEW
« no previous file with comments | « ppapi/thunk/enter.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698