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

Side by Side Diff: ppapi/native_client/src/trusted/plugin/service_runtime.cc

Issue 249183004: Implement open_resource in non-SFI mode. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 8 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 | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 * Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be 3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file. 4 * found in the LICENSE file.
5 */ 5 */
6 6
7 #define NACL_LOG_MODULE_NAME "Plugin_ServiceRuntime" 7 #define NACL_LOG_MODULE_NAME "Plugin_ServiceRuntime"
8 8
9 #include "ppapi/native_client/src/trusted/plugin/service_runtime.h" 9 #include "ppapi/native_client/src/trusted/plugin/service_runtime.h"
10 10
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 57
58 namespace plugin { 58 namespace plugin {
59 namespace { 59 namespace {
60 60
61 // For doing crude quota enforcement on writes to temp files. 61 // For doing crude quota enforcement on writes to temp files.
62 // We do not allow a temp file bigger than 128 MB for now. 62 // We do not allow a temp file bigger than 128 MB for now.
63 // There is currently a limit of 32M for nexe text size, so 128M 63 // There is currently a limit of 32M for nexe text size, so 128M
64 // should be plenty for static data 64 // should be plenty for static data
65 const int64_t kMaxTempQuota = 0x8000000; 65 const int64_t kMaxTempQuota = 0x8000000;
66 66
67 class OpenManifestEntryAsyncCallback {
68 public:
69 OpenManifestEntryAsyncCallback(PP_FileHandle* file_handle,
70 const pp::CompletionCallback& callback)
71 : file_handle_(file_handle),
72 callback_(callback) {
73 }
74
75 ~OpenManifestEntryAsyncCallback() {
76 if (callback_.pp_completion_callback().func)
77 callback_.RunAndClear(PP_ERROR_ABORTED);
78 }
79
80 void Run(int32_t pp_error) {
81 *file_handle_ = (pp_error == PP_OK) ? info_.desc : -1;
82 callback_.RunAndClear(pp_error);
83 delete this;
84 }
85
86 NaClFileInfo* mutable_info() { return &info_; }
87 pp::CompletionCallback pp_completion_callback() {
88 return pp::CompletionCallback(&RunTrampoline, this);
89 }
90
91 private:
92 static void RunTrampoline(void* user_data, int32_t pp_error) {
93 static_cast<OpenManifestEntryAsyncCallback*>(user_data)->Run(pp_error);
94 }
95
96 PP_FileHandle* file_handle_;
97 NaClFileInfo info_;
98 pp::CompletionCallback callback_;
99 DISALLOW_COPY_AND_ASSIGN(OpenManifestEntryAsyncCallback);
100 };
101
67 class ManifestService { 102 class ManifestService {
68 public: 103 public:
69 ManifestService(nacl::WeakRefAnchor* anchor, 104 ManifestService(nacl::WeakRefAnchor* anchor,
70 PluginReverseInterface* plugin_reverse) 105 PluginReverseInterface* plugin_reverse)
71 : anchor_(anchor), 106 : anchor_(anchor),
72 plugin_reverse_(plugin_reverse) { 107 plugin_reverse_(plugin_reverse) {
73 } 108 }
74 109
75 ~ManifestService() { 110 ~ManifestService() {
76 anchor_->Unref(); 111 anchor_->Unref();
77 } 112 }
78 113
79 bool Quit() { 114 bool Quit() {
80 delete this; 115 delete this;
81 return false; 116 return false;
82 } 117 }
83 118
84 bool StartupInitializationComplete() { 119 bool StartupInitializationComplete() {
85 // Release this instance if the ServiceRuntime is already destructed. 120 // Release this instance if the ServiceRuntime is already destructed.
86 if (anchor_->is_abandoned()) { 121 if (anchor_->is_abandoned()) {
87 delete this; 122 delete this;
88 return false; 123 return false;
89 } 124 }
90 125
91 plugin_reverse_->StartupInitializationComplete(); 126 plugin_reverse_->StartupInitializationComplete();
92 return true; 127 return true;
93 } 128 }
94 129
130 bool OpenResource(const char* entry_key, PP_FileHandle* file,
131 const pp::CompletionCallback& callback) {
132 // Release this instance if the ServiceRuntime is already destructed.
133 if (anchor_->is_abandoned()) {
134 delete this;
135 return false;
136 }
137
138 OpenManifestEntryAsyncCallback* open_manifest_callback =
139 new OpenManifestEntryAsyncCallback(file, callback);
140 plugin_reverse_->OpenManifestEntryAsync(
141 entry_key,
142 open_manifest_callback->mutable_info(),
143 open_manifest_callback->pp_completion_callback());
144 return true;
145 }
146
95 static PP_Bool QuitTrampoline(void* user_data) { 147 static PP_Bool QuitTrampoline(void* user_data) {
96 return PP_FromBool(static_cast<ManifestService*>(user_data)->Quit()); 148 return PP_FromBool(static_cast<ManifestService*>(user_data)->Quit());
97 } 149 }
98 150
99 static PP_Bool StartupInitializationCompleteTrampoline(void* user_data) { 151 static PP_Bool StartupInitializationCompleteTrampoline(void* user_data) {
100 return PP_FromBool(static_cast<ManifestService*>(user_data)-> 152 return PP_FromBool(static_cast<ManifestService*>(user_data)->
101 StartupInitializationComplete()); 153 StartupInitializationComplete());
102 } 154 }
103 155
156 static PP_Bool OpenResourceTrampoline(
157 void* user_data, const char* entry_key, PP_FileHandle* file,
158 struct PP_CompletionCallback callback) {
159 return PP_FromBool(
160 static_cast<ManifestService*>(user_data)->OpenResource(
161 entry_key, file,
162 pp::CompletionCallback(callback.func, callback.user_data)));
163 }
164
104 private: 165 private:
105 // Weak reference to check if plugin_reverse is legally accessible or not. 166 // Weak reference to check if plugin_reverse is legally accessible or not.
106 nacl::WeakRefAnchor* anchor_; 167 nacl::WeakRefAnchor* anchor_;
107 PluginReverseInterface* plugin_reverse_; 168 PluginReverseInterface* plugin_reverse_;
108 169
109 DISALLOW_COPY_AND_ASSIGN(ManifestService); 170 DISALLOW_COPY_AND_ASSIGN(ManifestService);
110 }; 171 };
111 172
112 // Vtable to pass functions to LaunchSelLdr. 173 // Vtable to pass functions to LaunchSelLdr.
113 const PP_ManifestService kManifestServiceVTable = { 174 const PPB_ManifestService kManifestServiceVTable = {
114 &ManifestService::QuitTrampoline, 175 &ManifestService::QuitTrampoline,
115 &ManifestService::StartupInitializationCompleteTrampoline, 176 &ManifestService::StartupInitializationCompleteTrampoline,
177 &ManifestService::OpenResourceTrampoline,
116 }; 178 };
117 179
118 } // namespace 180 } // namespace
119 181
120 PluginReverseInterface::PluginReverseInterface( 182 PluginReverseInterface::PluginReverseInterface(
121 nacl::WeakRefAnchor* anchor, 183 nacl::WeakRefAnchor* anchor,
122 Plugin* plugin, 184 Plugin* plugin,
123 const Manifest* manifest, 185 const Manifest* manifest,
124 ServiceRuntime* service_runtime, 186 ServiceRuntime* service_runtime,
125 pp::CompletionCallback init_done_cb, 187 pp::CompletionCallback init_done_cb,
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 // and invoke StreamAsFile with a completion callback that invokes 255 // and invoke StreamAsFile with a completion callback that invokes
194 // GetPOSIXFileDesc. 256 // GetPOSIXFileDesc.
195 bool PluginReverseInterface::OpenManifestEntry(nacl::string url_key, 257 bool PluginReverseInterface::OpenManifestEntry(nacl::string url_key,
196 struct NaClFileInfo* info) { 258 struct NaClFileInfo* info) {
197 bool op_complete = false; // NB: mu_ and cv_ also controls access to this! 259 bool op_complete = false; // NB: mu_ and cv_ also controls access to this!
198 // The to_open object is owned by the weak ref callback. Because this function 260 // The to_open object is owned by the weak ref callback. Because this function
199 // waits for the callback to finish, the to_open object will be deallocated on 261 // waits for the callback to finish, the to_open object will be deallocated on
200 // the main thread before this function can return. The pointers it contains 262 // the main thread before this function can return. The pointers it contains
201 // to stack variables will not leak. 263 // to stack variables will not leak.
202 OpenManifestEntryResource* to_open = 264 OpenManifestEntryResource* to_open =
203 new OpenManifestEntryResource(url_key, info, &op_complete); 265 new OpenManifestEntryResource(url_key, info, &op_complete,
266 pp::CompletionCallback());
204 CHECK(to_open != NULL); 267 CHECK(to_open != NULL);
205 NaClLog(4, "PluginReverseInterface::OpenManifestEntry: %s\n", 268 NaClLog(4, "PluginReverseInterface::OpenManifestEntry: %s\n",
206 url_key.c_str()); 269 url_key.c_str());
207 // This assumes we are not on the main thread. If false, we deadlock. 270 // This assumes we are not on the main thread. If false, we deadlock.
208 plugin::WeakRefCallOnMainThread( 271 plugin::WeakRefCallOnMainThread(
209 anchor_, 272 anchor_,
210 0, 273 0,
211 this, 274 this,
212 &plugin::PluginReverseInterface::OpenManifestEntry_MainThreadContinuation, 275 &plugin::PluginReverseInterface::OpenManifestEntry_MainThreadContinuation,
213 to_open); 276 to_open);
(...skipping 29 matching lines...) Expand all
243 if (info->desc == -1) { 306 if (info->desc == -1) {
244 // TODO(bsy,ncbray): what else should we do with the error? This 307 // TODO(bsy,ncbray): what else should we do with the error? This
245 // is a runtime error that may simply be a programming error in 308 // is a runtime error that may simply be a programming error in
246 // the untrusted code, or it may be something else wrong w/ the 309 // the untrusted code, or it may be something else wrong w/ the
247 // manifest. 310 // manifest.
248 NaClLog(4, "OpenManifestEntry: failed for key %s", url_key.c_str()); 311 NaClLog(4, "OpenManifestEntry: failed for key %s", url_key.c_str());
249 } 312 }
250 return true; 313 return true;
251 } 314 }
252 315
316 void PluginReverseInterface::OpenManifestEntryAsync(
317 const nacl::string& entry_key,
318 struct NaClFileInfo* info,
319 const pp::CompletionCallback& callback) {
320 bool op_complete = false;
321 OpenManifestEntryResource to_open(
322 entry_key, info, &op_complete, callback);
323 OpenManifestEntry_MainThreadContinuation(&to_open, PP_OK);
324 }
325
253 // Transfer point from OpenManifestEntry() which runs on the main thread 326 // Transfer point from OpenManifestEntry() which runs on the main thread
254 // (Some PPAPI actions -- like StreamAsFile -- can only run on the main thread). 327 // (Some PPAPI actions -- like StreamAsFile -- can only run on the main thread).
255 // OpenManifestEntry() is waiting on a condvar for this continuation to 328 // OpenManifestEntry() is waiting on a condvar for this continuation to
256 // complete. We Broadcast and awaken OpenManifestEntry() whenever we are done 329 // complete. We Broadcast and awaken OpenManifestEntry() whenever we are done
257 // either here, or in a later MainThreadContinuation step, if there are 330 // either here, or in a later MainThreadContinuation step, if there are
258 // multiple steps. 331 // multiple steps.
259 void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation( 332 void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation(
260 OpenManifestEntryResource* p, 333 OpenManifestEntryResource* p,
261 int32_t err) { 334 int32_t err) {
262 UNREFERENCED_PARAMETER(err); 335 UNREFERENCED_PARAMETER(err);
263 // CallOnMainThread continuations always called with err == PP_OK. 336 // CallOnMainThread continuations always called with err == PP_OK.
264 337
265 NaClLog(4, "Entered OpenManifestEntry_MainThreadContinuation\n"); 338 NaClLog(4, "Entered OpenManifestEntry_MainThreadContinuation\n");
266 339
267 std::string mapped_url; 340 std::string mapped_url;
268 PP_PNaClOptions pnacl_options = {PP_FALSE, PP_FALSE, 2}; 341 PP_PNaClOptions pnacl_options = {PP_FALSE, PP_FALSE, 2};
269 ErrorInfo error_info; 342 ErrorInfo error_info;
270 if (!manifest_->ResolveKey(p->url, &mapped_url, 343 if (!manifest_->ResolveKey(p->url, &mapped_url,
271 &pnacl_options, &error_info)) { 344 &pnacl_options, &error_info)) {
272 NaClLog(4, "OpenManifestEntry_MainThreadContinuation: ResolveKey failed\n"); 345 NaClLog(4, "OpenManifestEntry_MainThreadContinuation: ResolveKey failed\n");
273 NaClLog(4, 346 NaClLog(4,
274 "Error code %d, string %s\n", 347 "Error code %d, string %s\n",
275 error_info.error_code(), 348 error_info.error_code(),
276 error_info.message().c_str()); 349 error_info.message().c_str());
277 // Failed, and error_info has the details on what happened. Wake 350 // Failed, and error_info has the details on what happened. Wake
278 // up requesting thread -- we are done. 351 // up requesting thread -- we are done.
279 nacl::MutexLocker take(&mu_); 352 {
280 *p->op_complete_ptr = true; // done... 353 nacl::MutexLocker take(&mu_);
281 p->file_info->desc = -1; // but failed. 354 *p->op_complete_ptr = true; // done...
282 NaClXCondVarBroadcast(&cv_); 355 p->file_info->desc = -1; // but failed.
356 NaClXCondVarBroadcast(&cv_);
357 }
358 if (p->callback.pp_completion_callback().func)
359 p->callback.RunAndClear(PP_OK);
283 return; 360 return;
284 } 361 }
285 NaClLog(4, 362 NaClLog(4,
286 "OpenManifestEntry_MainThreadContinuation: " 363 "OpenManifestEntry_MainThreadContinuation: "
287 "ResolveKey: %s -> %s (pnacl_translate(%d))\n", 364 "ResolveKey: %s -> %s (pnacl_translate(%d))\n",
288 p->url.c_str(), mapped_url.c_str(), pnacl_options.translate); 365 p->url.c_str(), mapped_url.c_str(), pnacl_options.translate);
289 366
290 if (pnacl_options.translate) { 367 if (pnacl_options.translate) {
291 // Requires PNaCl translation, but that's not supported. 368 // Requires PNaCl translation, but that's not supported.
292 NaClLog(4, 369 NaClLog(4,
293 "OpenManifestEntry_MainThreadContinuation: " 370 "OpenManifestEntry_MainThreadContinuation: "
294 "Requires PNaCl translation -- not supported\n"); 371 "Requires PNaCl translation -- not supported\n");
295 nacl::MutexLocker take(&mu_); 372 {
296 *p->op_complete_ptr = true; // done... 373 nacl::MutexLocker take(&mu_);
297 p->file_info->desc = -1; // but failed. 374 *p->op_complete_ptr = true; // done...
298 NaClXCondVarBroadcast(&cv_); 375 p->file_info->desc = -1; // but failed.
376 NaClXCondVarBroadcast(&cv_);
377 }
378 if (p->callback.pp_completion_callback().func)
379 p->callback.RunAndClear(PP_OK);
299 return; 380 return;
300 } 381 }
301 382
302 if (PnaclUrls::IsPnaclComponent(mapped_url)) { 383 if (PnaclUrls::IsPnaclComponent(mapped_url)) {
303 // Special PNaCl support files, that are installed on the 384 // Special PNaCl support files, that are installed on the
304 // user machine. 385 // user machine.
305 int32_t fd = PnaclResources::GetPnaclFD( 386 int32_t fd = PnaclResources::GetPnaclFD(
306 plugin_, 387 plugin_,
307 PnaclUrls::PnaclComponentURLToFilename(mapped_url).c_str()); 388 PnaclUrls::PnaclComponentURLToFilename(mapped_url).c_str());
308 if (fd < 0) { 389 if (fd < 0) {
309 // We checked earlier if the pnacl component wasn't installed 390 // We checked earlier if the pnacl component wasn't installed
310 // yet, so this shouldn't happen. At this point, we can't do much 391 // yet, so this shouldn't happen. At this point, we can't do much
311 // anymore, so just continue with an invalid fd. 392 // anymore, so just continue with an invalid fd.
312 NaClLog(4, 393 NaClLog(4,
313 "OpenManifestEntry_MainThreadContinuation: " 394 "OpenManifestEntry_MainThreadContinuation: "
314 "GetReadonlyPnaclFd failed\n"); 395 "GetReadonlyPnaclFd failed\n");
315 } 396 }
316 nacl::MutexLocker take(&mu_); 397 {
317 *p->op_complete_ptr = true; // done! 398 nacl::MutexLocker take(&mu_);
318 // TODO(ncbray): enable the fast loading and validation paths for this 399 *p->op_complete_ptr = true; // done!
319 // type of file. 400 // TODO(ncbray): enable the fast loading and validation paths for this
320 p->file_info->desc = fd; 401 // type of file.
321 NaClXCondVarBroadcast(&cv_); 402 p->file_info->desc = fd;
403 NaClXCondVarBroadcast(&cv_);
404 }
322 NaClLog(4, 405 NaClLog(4,
323 "OpenManifestEntry_MainThreadContinuation: GetPnaclFd okay\n"); 406 "OpenManifestEntry_MainThreadContinuation: GetPnaclFd okay\n");
407 if (p->callback.pp_completion_callback().func)
408 p->callback.RunAndClear(PP_OK);
324 return; 409 return;
325 } 410 }
326 411
327 // Hereafter, normal files. 412 // Hereafter, normal files.
328 413
329 // Because p is owned by the callback of this invocation, so it is necessary 414 // Because p is owned by the callback of this invocation, so it is necessary
330 // to create another instance. 415 // to create another instance.
331 OpenManifestEntryResource* open_cont = new OpenManifestEntryResource(*p); 416 OpenManifestEntryResource* open_cont = new OpenManifestEntryResource(*p);
332 open_cont->url = mapped_url; 417 open_cont->url = mapped_url;
418 // Callback is now delegated from p to open_cont. So, here we manually clear
419 // complete callback.
420 p->callback = pp::CompletionCallback();
333 pp::CompletionCallback stream_cc = WeakRefNewCallback( 421 pp::CompletionCallback stream_cc = WeakRefNewCallback(
334 anchor_, 422 anchor_,
335 this, 423 this,
336 &PluginReverseInterface::StreamAsFile_MainThreadContinuation, 424 &PluginReverseInterface::StreamAsFile_MainThreadContinuation,
337 open_cont); 425 open_cont);
338 426
339 if (!plugin_->StreamAsFile(mapped_url, stream_cc)) { 427 if (!plugin_->StreamAsFile(mapped_url, stream_cc)) {
340 NaClLog(4, 428 NaClLog(4,
341 "OpenManifestEntry_MainThreadContinuation: " 429 "OpenManifestEntry_MainThreadContinuation: "
342 "StreamAsFile failed\n"); 430 "StreamAsFile failed\n");
343 // Here, StreamAsFile is failed and stream_cc is not called. 431 // Here, StreamAsFile is failed and stream_cc is not called.
344 // However, open_cont will be released only by the invocation. 432 // However, open_cont will be released only by the invocation.
345 // So, we manually call it here with error. 433 // So, we manually call it here with error.
346 stream_cc.Run(PP_ERROR_FAILED); 434 stream_cc.Run(PP_ERROR_FAILED);
347 return; 435 return;
348 } 436 }
349 437
350 NaClLog(4, "OpenManifestEntry_MainThreadContinuation: StreamAsFile okay\n"); 438 NaClLog(4, "OpenManifestEntry_MainThreadContinuation: StreamAsFile okay\n");
351 // p is deleted automatically 439 // p is deleted automatically
352 } 440 }
353 441
354 void PluginReverseInterface::StreamAsFile_MainThreadContinuation( 442 void PluginReverseInterface::StreamAsFile_MainThreadContinuation(
355 OpenManifestEntryResource* p, 443 OpenManifestEntryResource* p,
356 int32_t result) { 444 int32_t result) {
357 NaClLog(4, 445 NaClLog(4,
358 "Entered StreamAsFile_MainThreadContinuation\n"); 446 "Entered StreamAsFile_MainThreadContinuation\n");
359 447
360 nacl::MutexLocker take(&mu_); 448 {
361 if (result == PP_OK) { 449 nacl::MutexLocker take(&mu_);
362 NaClLog(4, "StreamAsFile_MainThreadContinuation: GetFileInfo(%s)\n", 450 if (result == PP_OK) {
363 p->url.c_str()); 451 NaClLog(4, "StreamAsFile_MainThreadContinuation: GetFileInfo(%s)\n",
364 *p->file_info = plugin_->GetFileInfo(p->url); 452 p->url.c_str());
453 *p->file_info = plugin_->GetFileInfo(p->url);
365 454
366 NaClLog(4, 455 NaClLog(4,
367 "StreamAsFile_MainThreadContinuation: PP_OK, desc %d\n", 456 "StreamAsFile_MainThreadContinuation: PP_OK, desc %d\n",
368 p->file_info->desc); 457 p->file_info->desc);
369 } else { 458 } else {
370 NaClLog(4, 459 NaClLog(
371 "StreamAsFile_MainThreadContinuation: !PP_OK, setting desc -1\n"); 460 4,
372 p->file_info->desc = -1; 461 "StreamAsFile_MainThreadContinuation: !PP_OK, setting desc -1\n");
462 p->file_info->desc = -1;
463 }
464 *p->op_complete_ptr = true;
465 NaClXCondVarBroadcast(&cv_);
373 } 466 }
374 *p->op_complete_ptr = true; 467 if (p->callback.pp_completion_callback().func)
375 NaClXCondVarBroadcast(&cv_); 468 p->callback.RunAndClear(PP_OK);
376 } 469 }
377 470
378 bool PluginReverseInterface::CloseManifestEntry(int32_t desc) { 471 bool PluginReverseInterface::CloseManifestEntry(int32_t desc) {
379 bool op_complete = false; 472 bool op_complete = false;
380 bool op_result; 473 bool op_result;
381 CloseManifestEntryResource* to_close = 474 CloseManifestEntryResource* to_close =
382 new CloseManifestEntryResource(desc, &op_complete, &op_result); 475 new CloseManifestEntryResource(desc, &op_complete, &op_result);
383 476
384 plugin::WeakRefCallOnMainThread( 477 plugin::WeakRefCallOnMainThread(
385 anchor_, 478 anchor_,
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 894
802 nacl::string ServiceRuntime::GetCrashLogOutput() { 895 nacl::string ServiceRuntime::GetCrashLogOutput() {
803 if (NULL != subprocess_.get()) { 896 if (NULL != subprocess_.get()) {
804 return subprocess_->GetCrashLogOutput(); 897 return subprocess_->GetCrashLogOutput();
805 } else { 898 } else {
806 return std::string(); 899 return std::string();
807 } 900 }
808 } 901 }
809 902
810 } // namespace plugin 903 } // namespace plugin
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698