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

Side by Side Diff: src/trusted/plugin/srpc/plugin.cc

Issue 2981011: Move plugin/srpc contents to the more appropriately named plugin/common.... (Closed) Base URL: http://nativeclient.googlecode.com/svn/trunk/src/native_client/
Patch Set: '' Created 10 years, 5 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
« no previous file with comments | « src/trusted/plugin/srpc/plugin.h ('k') | src/trusted/plugin/srpc/portable_handle.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2008 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can
4 * be found in the LICENSE file.
5 */
6
7 #include "native_client/src/trusted/plugin/srpc/plugin.h"
8
9 #include <assert.h>
10 #include <fcntl.h>
11 #include <stdarg.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15
16 #include <sys/types.h>
17 #include <sys/stat.h>
18
19 #include "native_client/src/include/nacl_string.h"
20 #include "native_client/src/include/portability_string.h"
21 #include "native_client/src/trusted/desc/nacl_desc_base.h"
22 #include "native_client/src/trusted/desc/nacl_desc_conn_cap.h"
23 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h"
24 #include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h"
25 #include "native_client/src/trusted/plugin/npapi/video.h"
26 #include "native_client/src/trusted/plugin/origin.h"
27 #include "native_client/src/trusted/plugin/srpc/browser_interface.h"
28 #include "native_client/src/trusted/plugin/srpc/connected_socket.h"
29 #include "native_client/src/trusted/plugin/srpc/nexe_arch.h"
30 #include "native_client/src/trusted/plugin/srpc/scriptable_handle.h"
31 #include "native_client/src/trusted/plugin/srpc/service_runtime.h"
32 #include "native_client/src/trusted/plugin/srpc/shared_memory.h"
33 #include "native_client/src/trusted/plugin/srpc/socket_address.h"
34 #include "native_client/src/trusted/plugin/srpc/stream_shm_buffer.h"
35 #include "native_client/src/trusted/plugin/srpc/string_encoding.h"
36 #include "native_client/src/trusted/plugin/srpc/utility.h"
37
38 namespace {
39
40 static int32_t stringToInt32(char* src) {
41 return strtol(src, // NOLINT(runtime/deprecated_fn)
42 static_cast<char**>(NULL), 0);
43 }
44
45 // TODO(sehr): using a static jmpbuf here has several problems. Notably we
46 // cannot reliably handle errors when there are multiple plugins in the same
47 // process. Issue 605.
48 PLUGIN_JMPBUF g_LoaderEnv;
49
50 bool ShmFactory(void* obj, plugin::SrpcParams* params) {
51 plugin::Plugin* plugin = reinterpret_cast<plugin::Plugin*>(obj);
52
53 plugin::SharedMemory* portable_shared_memory =
54 plugin::SharedMemory::New(plugin, params->ins()[0]->u.ival);
55 plugin::ScriptableHandle* shared_memory =
56 plugin->browser_interface()->NewScriptableHandle(portable_shared_memory);
57 if (NULL == shared_memory) {
58 params->set_exception_string("out of memory");
59 portable_shared_memory->Delete();
60 return false;
61 }
62
63 params->outs()[0]->tag = NACL_SRPC_ARG_TYPE_OBJECT;
64 params->outs()[0]->u.oval = shared_memory;
65 return true;
66 }
67
68 bool DefaultSocketAddress(void* obj, plugin::SrpcParams* params) {
69 plugin::Plugin* plugin = reinterpret_cast<plugin::Plugin*>(obj);
70 if (NULL == plugin->socket_address()) {
71 params->set_exception_string("no socket address");
72 return false;
73 }
74 plugin->socket_address()->AddRef();
75 // Plug the scriptable object into the return values.
76 params->outs()[0]->tag = NACL_SRPC_ARG_TYPE_OBJECT;
77 params->outs()[0]->u.oval = plugin->socket_address();
78 return true;
79 }
80
81 // A method to test the cost of invoking a method in a plugin without
82 // making an RPC to the service runtime. Used for performance evaluation.
83 bool NullPluginMethod(void* obj, plugin::SrpcParams* params) {
84 UNREFERENCED_PARAMETER(obj);
85 params->outs()[0]->tag = NACL_SRPC_ARG_TYPE_INT;
86 params->outs()[0]->u.ival = 0;
87 return true;
88 }
89
90 bool GetModuleReadyProperty(void* obj, plugin::SrpcParams* params) {
91 plugin::Plugin* plugin = reinterpret_cast<plugin::Plugin*>(obj);
92 if (plugin->socket()) {
93 params->outs()[0]->u.ival = 1;
94 } else {
95 params->outs()[0]->u.ival = 0;
96 }
97 return true;
98 }
99
100 bool SetModuleReadyProperty(void* obj, plugin::SrpcParams* params) {
101 UNREFERENCED_PARAMETER(obj);
102 params->set_exception_string("__moduleReady is a read-only property");
103 return false;
104 }
105
106 bool GetNexesProperty(void* obj, plugin::SrpcParams* params) {
107 UNREFERENCED_PARAMETER(obj);
108 UNREFERENCED_PARAMETER(params);
109 // Note, "get" must be present in the method map for "set" to work.
110 PLUGIN_PRINTF(("GetNexesProperty not yet implemented.\n"));
111 return false;
112 }
113
114 // Update "nexes", a write-only property that computes a value to
115 // assign to the "src" property based on the supported sandbox.
116 bool SetNexesProperty(void* obj, plugin::SrpcParams* params) {
117 return reinterpret_cast<plugin::Plugin*>(obj)->
118 SetNexesPropertyImpl(params->ins()[0]->u.sval);
119 }
120
121 bool GetSrcProperty(void* obj, plugin::SrpcParams* params) {
122 plugin::Plugin* plugin = reinterpret_cast<plugin::Plugin*>(obj);
123 if (plugin->logical_url() != NULL) {
124 params->outs()[0]->u.sval = strdup(plugin->logical_url());
125 PLUGIN_PRINTF(("GetSrcProperty 'src' = %s\n", plugin->logical_url()));
126 return true;
127 } else {
128 // (NULL is not an acceptable SRPC result.)
129 PLUGIN_PRINTF(("GetSrcProperty 'src' failed\n"));
130 return false;
131 }
132 }
133
134 bool SetSrcProperty(void* obj, plugin::SrpcParams* params) {
135 PLUGIN_PRINTF(("SetSrcProperty\n"));
136 return reinterpret_cast<plugin::Plugin*>(obj)->
137 SetSrcPropertyImpl(params->ins()[0]->u.sval);
138 }
139
140 bool GetHeightProperty(void* obj, plugin::SrpcParams* params) {
141 plugin::Plugin* plugin = reinterpret_cast<plugin::Plugin*>(obj);
142 params->outs()[0]->u.ival = plugin->height();
143 return true;
144 }
145
146 bool SetHeightProperty(void* obj, plugin::SrpcParams* params) {
147 plugin::Plugin* plugin = reinterpret_cast<plugin::Plugin*>(obj);
148 plugin->set_height(params->ins()[0]->u.ival);
149 return true;
150 }
151
152 bool GetWidthProperty(void* obj, plugin::SrpcParams* params) {
153 plugin::Plugin* plugin = reinterpret_cast<plugin::Plugin*>(obj);
154 params->outs()[0]->u.ival = plugin->width();
155 return true;
156 }
157
158 bool SetWidthProperty(void* obj, plugin::SrpcParams* params) {
159 plugin::Plugin* plugin = reinterpret_cast<plugin::Plugin*>(obj);
160 plugin->set_width(params->ins()[0]->u.ival);
161 return true;
162 }
163
164 bool GetVideoUpdateModeProperty(void* obj, plugin::SrpcParams* params) {
165 plugin::Plugin* plugin = reinterpret_cast<plugin::Plugin*>(obj);
166 params->outs()[0]->u.ival = plugin->video_update_mode();
167 return true;
168 }
169
170 bool SetVideoUpdateModeProperty(void* obj, plugin::SrpcParams* params) {
171 plugin::Plugin* plugin = reinterpret_cast<plugin::Plugin*>(obj);
172 plugin->set_video_update_mode(params->ins()[0]->u.ival);
173 return true;
174 }
175
176 void SignalHandler(int value) {
177 PLUGIN_PRINTF(("Plugin::SignalHandler()\n"));
178 PLUGIN_LONGJMP(g_LoaderEnv, value);
179 }
180
181 } // namespace
182
183 namespace plugin {
184
185 // TODO(mseaborn): Although this will usually not block, it will
186 // block if the socket's buffer fills up.
187 bool Plugin::SendAsyncMessage(void* obj, SrpcParams* params,
188 nacl::DescWrapper** fds, int fds_count) {
189 Plugin* plugin = reinterpret_cast<Plugin*>(obj);
190 if (plugin->service_runtime_ == NULL) {
191 params->set_exception_string("No subprocess running");
192 return false;
193 }
194
195 // TODO(mseaborn): Handle strings containing NULLs. This might
196 // involve using a different SRPC type.
197 char* utf8string = params->ins()[0]->u.sval;
198 char* data;
199 size_t data_size;
200 if (!ByteStringFromUTF8(utf8string, strlen(utf8string), &data, &data_size)) {
201 params->set_exception_string("Invalid string");
202 return false;
203 }
204 nacl::DescWrapper::MsgIoVec iov;
205 nacl::DescWrapper::MsgHeader message;
206 iov.base = data;
207 iov.length = static_cast<nacl_abi_size_t>(data_size);
208 message.iov = &iov;
209 message.iov_length = 1;
210 message.ndescv = fds;
211 message.ndescv_length = fds_count;
212 message.flags = 0;
213 nacl::DescWrapper* socket = plugin->service_runtime_->async_send_desc;
214 ssize_t sent = socket->SendMsg(&message, 0);
215 free(data);
216 if (sent < 0) {
217 params->set_exception_string("Error sending message");
218 return false;
219 }
220 return true;
221 }
222
223 // TODO(mseaborn): Combine __sendAsyncMessage0 and __sendAsyncMessage1
224 // into a single method that takes an array of FDs. SRPC does not
225 // provide a handle array type so there is not a simple way to do
226 // this.
227 bool Plugin::SendAsyncMessage0(void* obj, SrpcParams* params) {
228 return SendAsyncMessage(obj, params, NULL, 0);
229 }
230
231 bool Plugin::SendAsyncMessage1(void* obj, SrpcParams* params) {
232 Plugin* plugin = reinterpret_cast<Plugin*>(obj);
233 nacl::DescWrapper* fd_to_send =
234 plugin->wrapper_factory()->MakeGeneric(params->ins()[1]->u.hval);
235 return SendAsyncMessage(obj, params, &fd_to_send, 1);
236 }
237
238 static int const kAbiHeaderBuffer = 256; // must be at least EI_ABIVERSION + 1
239
240 void Plugin::LoadMethods() {
241 // Methods supported by Plugin.
242 AddMethodCall(ShmFactory, "__shmFactory", "i", "h");
243 AddMethodCall(DefaultSocketAddress, "__defaultSocketAddress", "", "h");
244 AddMethodCall(NullPluginMethod, "__nullPluginMethod", "s", "i");
245 AddMethodCall(SendAsyncMessage0, "__sendAsyncMessage0", "s", "");
246 AddMethodCall(SendAsyncMessage1, "__sendAsyncMessage1", "sh", "");
247 // Properties implemented by Plugin.
248 AddPropertyGet(GetHeightProperty, "height", "i");
249 AddPropertySet(SetHeightProperty, "height", "i");
250 AddPropertyGet(GetModuleReadyProperty, "__moduleReady", "i");
251 AddPropertySet(SetModuleReadyProperty, "__moduleReady", "i");
252 AddPropertyGet(GetNexesProperty, "nexes", "s");
253 AddPropertySet(SetNexesProperty, "nexes", "s");
254 AddPropertyGet(GetSrcProperty, "src", "s");
255 AddPropertySet(SetSrcProperty, "src", "s");
256 AddPropertyGet(GetVideoUpdateModeProperty, "videoUpdateMode", "i");
257 AddPropertySet(SetVideoUpdateModeProperty, "videoUpdateMode", "i");
258 AddPropertyGet(GetWidthProperty, "width", "i");
259 AddPropertySet(SetWidthProperty, "width", "i");
260 }
261
262 bool Plugin::HasMethodEx(uintptr_t method_id, CallType call_type) {
263 if (NULL == socket_) {
264 return false;
265 }
266 return socket_->handle()->HasMethod(method_id, call_type);
267 }
268
269 bool Plugin::InvokeEx(uintptr_t method_id,
270 CallType call_type,
271 SrpcParams* params) {
272 if (NULL == socket_) {
273 return false;
274 }
275 return socket_->handle()->Invoke(method_id, call_type, params);
276 }
277
278 bool Plugin::InitParamsEx(uintptr_t method_id,
279 CallType call_type,
280 SrpcParams* params) {
281 if (NULL == socket_) {
282 return false;
283 }
284 return socket_->handle()->InitParams(method_id, call_type, params);
285 }
286
287
288 bool Plugin::SetNexesPropertyImpl(const char* nexes_attr) {
289 PLUGIN_PRINTF(("Plugin::SetNexesPropertyImpl: %s\n", nexes_attr));
290 nacl::string result;
291 if (!GetNexeURL(nexes_attr, &result)) {
292 // TODO(adonovan): Ideally we would print to the browser's
293 // JavaScript console: alert popups are annoying, and no-one can
294 // be expected to read stderr.
295 PLUGIN_PRINTF(("%s\n", result.c_str()));
296 browser_interface()->Alert(instance_id(), result);
297 return false;
298 } else {
299 return SetSrcPropertyImpl(result);
300 }
301 }
302
303 bool Plugin::SetSrcPropertyImpl(const nacl::string& url) {
304 if (NULL != service_runtime_) {
305 PLUGIN_PRINTF(("Plugin::SetProperty: unloading previous\n"));
306 // Plugin owns socket_address_ and socket_, so when we change to a new
307 // socket we need to give up ownership of the old one.
308 socket_address_->Unref();
309 socket_address_ = NULL;
310 socket_->Unref();
311 socket_ = NULL;
312 service_runtime_->Shutdown();
313 delete service_runtime_;
314 service_runtime_ = NULL;
315 ShutDownReceiveThread();
316 }
317 return RequestNaClModule(url);
318 }
319
320 bool Plugin::Init(BrowserInterface* browser_interface,
321 InstanceIdentifier instance_id,
322 int argc,
323 char* argn[],
324 char* argv[]) {
325 PLUGIN_PRINTF(("Plugin::Init: instance_id=%p\n",
326 reinterpret_cast<void*>(instance_id)));
327
328 browser_interface_ = browser_interface;
329 instance_id_ = instance_id;
330 // Remember the embed/object argn/argv pairs.
331 argn_ = new(std::nothrow) char*[argc];
332 argv_ = new(std::nothrow) char*[argc];
333 argc_ = 0;
334 // Set up the height and width attributes if passed (for Opera)
335 for (int i = 0; i < argc; ++i) {
336 if (!strncmp(argn[i], "height", 7)) {
337 set_height(stringToInt32(argv[i]));
338 } else if (!strncmp(argn[i], "width", 6)) {
339 set_width(stringToInt32(argv[i]));
340 } else if (!strncmp(argn[i], "update", 7)) {
341 set_video_update_mode(stringToInt32(argv[i]));
342 } else {
343 if (NULL != argn_ && NULL != argv_) {
344 argn_[argc_] = strdup(argn[i]);
345 argv_[argc_] = strdup(argv[i]);
346 if (NULL == argn_[argc_] ||
347 NULL == argv_[argc_]) {
348 // Give up on passing arguments.
349 free(argn_[argc_]);
350 free(argv_[argc_]);
351 continue;
352 }
353 ++argc_;
354 }
355 }
356 }
357 // TODO(sehr): this leaks strings if there is a subsequent failure.
358
359 // Set up the factory used to produce DescWrappers.
360 wrapper_factory_ = new nacl::DescWrapperFactory();
361 if (NULL == wrapper_factory_) {
362 return false;
363 }
364 PLUGIN_PRINTF(("Plugin::Init: wrapper_factory=%p\n",
365 reinterpret_cast<void*>(wrapper_factory_)));
366
367 // Check that the origin is allowed.
368 nacl::string href = "";
369 if (browser_interface_->GetOrigin(instance_id_, &href)) {
370 origin_ = nacl::UrlToOrigin(href);
371 PLUGIN_PRINTF(("Plugin::Init: origin=%s\n", origin_.c_str()));
372 // Check that origin is in the list of permitted origins.
373 origin_valid_ = nacl::OriginIsInWhitelist(origin_);
374 // This implementation of same-origin policy does not take
375 // document.domain element into account.
376 }
377
378 // Set up the scriptable methods for the plugin.
379 LoadMethods();
380
381 // If the <embed src='...'> attr was defined, the browser would have
382 // implicitly called GET on it, which calls Load() and set_logical_url().
383 // In the absence of this attr, we use the "nexes" attribute if present.
384 if (logical_url() == NULL) {
385 const char* nexes_attr = LookupArgument("nexes");
386 if (nexes_attr != NULL) {
387 SetNexesPropertyImpl(nexes_attr);
388 }
389 }
390
391 PLUGIN_PRINTF(("Plugin::Init: done\n"));
392 // Return success.
393 return true;
394 }
395
396 Plugin::Plugin()
397 : service_runtime_(NULL),
398 receive_thread_running_(false),
399 argc_(-1),
400 argn_(NULL),
401 argv_(NULL),
402 socket_address_(NULL),
403 socket_(NULL),
404 local_url_(NULL),
405 logical_url_(NULL),
406 origin_valid_(false),
407 height_(0),
408 width_(0),
409 video_update_mode_(kVideoUpdatePluginPaint),
410 wrapper_factory_(NULL) {
411 PLUGIN_PRINTF(("Plugin::Plugin(%p)\n", static_cast<void*>(this)));
412 }
413
414 void Plugin::Invalidate() {
415 socket_address_ = NULL;
416 socket_ = NULL;
417 }
418
419 void Plugin::ShutDownReceiveThread() {
420 if (receive_thread_running_) {
421 NaClThreadJoin(&receive_thread_);
422 receive_thread_running_ = false;
423 }
424 }
425
426 Plugin::~Plugin() {
427 PLUGIN_PRINTF(("Plugin::~Plugin(%p)\n", static_cast<void*>(this)));
428
429 // After invalidation, the browser does not respect reference counting,
430 // so we shut down here what we can and prevent attempts to shut down
431 // other linked structures in Deallocate.
432
433 // Free the socket address for this plugin, if any.
434 if (NULL != socket_address_) {
435 PLUGIN_PRINTF(("Plugin::~Plugin: unloading\n"));
436 // Deallocating a plugin releases ownership of the socket address.
437 socket_address_->Unref();
438 }
439 // Free the connected socket for this plugin, if any.
440 if (NULL != socket_) {
441 PLUGIN_PRINTF(("Plugin::~Plugin: unloading\n"));
442 // Deallocating a plugin releases ownership of the socket.
443 socket_->Unref();
444 }
445 // Clear the pointers to the connected socket and service runtime interface.
446 socket_address_ = NULL;
447 socket_ = NULL;
448 delete service_runtime_;
449 service_runtime_ = NULL;
450 ShutDownReceiveThread();
451 PLUGIN_PRINTF(("Plugin::~Plugin(%p)\n", static_cast<void*>(this)));
452 free(local_url_);
453 free(logical_url_);
454 }
455
456 void Plugin::set_local_url(const char* url) {
457 PLUGIN_PRINTF(("Plugin::set_local_url(%s)\n", url));
458 if (local_url_ != NULL) free(local_url_);
459 local_url_ = strdup(url);
460 }
461
462 void Plugin::set_logical_url(const char* url) {
463 PLUGIN_PRINTF(("Plugin::set_logical_url(%s)\n", url));
464 if (logical_url_ != NULL) free(logical_url_);
465 logical_url_ = strdup(url);
466 }
467
468 // Create a new service node from a downloaded service.
469 bool Plugin::Load(nacl::string logical_url, const char* local_url) {
470 return Load(logical_url, local_url, static_cast<StreamShmBuffer*>(NULL));
471 }
472
473 bool Plugin::Load(nacl::string logical_url,
474 const char* local_url,
475 StreamShmBuffer* shmbufp) {
476 BrowserInterface* browser_interface = this->browser_interface();
477
478 if (NULL == shmbufp) {
479 PLUGIN_PRINTF(("Plugin::Load(%s)\n", local_url));
480 } else {
481 PLUGIN_PRINTF(("Plugin::Load(%p)\n", reinterpret_cast<void*>(shmbufp)));
482 }
483
484 // Save the origin and local_url.
485 set_nacl_module_origin(nacl::UrlToOrigin(logical_url));
486 set_logical_url(logical_url.c_str());
487 set_local_url(local_url);
488 // If the page origin where the EMBED/OBJECT tag occurs is not in
489 // the whitelist, refuse to load. If the NaCl module's origin is
490 // not in the whitelist, also refuse to load.
491 // TODO(adonovan): JavaScript permits cross-origin loading, and so
492 // does Chrome ; why don't we?
493 if (!origin_valid_ || !nacl::OriginIsInWhitelist(nacl_module_origin())) {
494 nacl::string message = nacl::string("Load failed: NaCl module ") +
495 logical_url + " does not come ""from a whitelisted source. "
496 "See native_client/src/trusted/plugin/origin.cc for the list.";
497 browser_interface->Alert(instance_id(), message.c_str());
498 return false;
499 }
500 // Catch any bad accesses, etc., while loading.
501 ScopedCatchSignals sigcatcher(
502 (ScopedCatchSignals::SigHandlerType) SignalHandler);
503 if (PLUGIN_SETJMP(g_LoaderEnv, 1)) {
504 return false;
505 }
506
507 PLUGIN_PRINTF(("Load: NaCl module from '%s'\n", local_url_));
508
509 // Check ELF magic and ABI version compatibility.
510 bool success = false;
511 nacl::string error_string;
512 if (NULL == shmbufp) {
513 success = browser_interface->MightBeElfExecutable(local_url_,
514 &error_string);
515 } else {
516 // Read out first chunk for MightBeElfExecutable; this suffices for
517 // ELF headers etc.
518 char elf_hdr_buf[kAbiHeaderBuffer];
519 ssize_t result;
520 result = shmbufp->read(0, sizeof elf_hdr_buf, elf_hdr_buf);
521 if (sizeof elf_hdr_buf == result) { // (const char*)(elf_hdr_buf)
522 success = browser_interface->MightBeElfExecutable(elf_hdr_buf,
523 sizeof elf_hdr_buf,
524 &error_string);
525 }
526 }
527 if (!success) {
528 browser_interface->Alert(instance_id(), error_string);
529 return false;
530 }
531 // Load a file via a forked sel_ldr process.
532 service_runtime_ = new(std::nothrow) ServiceRuntime(browser_interface, this);
533 if (NULL == service_runtime_) {
534 PLUGIN_PRINTF((" ServiceRuntime Ctor failed\n"));
535 browser_interface->Alert(instance_id(),
536 "ServiceRuntime Ctor failed");
537 return false;
538 }
539 bool service_runtime_started = false;
540 if (NULL == shmbufp) {
541 service_runtime_started = service_runtime_->Start(local_url_);
542 } else {
543 int32_t size;
544 NaClDesc* raw_desc = shmbufp->shm(&size);
545 if (NULL == raw_desc) {
546 PLUGIN_PRINTF((" extracting shm failed\n"));
547 return false;
548 }
549 nacl::DescWrapper* wrapped_shm =
550 wrapper_factory_->MakeGeneric(NaClDescRef(raw_desc));
551 service_runtime_started = service_runtime_->Start(local_url_, wrapped_shm);
552 // Start consumes the wrapped_shm.
553 }
554 if (!service_runtime_started) {
555 PLUGIN_PRINTF((" Load: FAILED to start service runtime"));
556 browser_interface->Alert(instance_id(),
557 "Load: FAILED to start service runtime");
558 return false;
559 }
560
561 PLUGIN_PRINTF((" Load: started sel_ldr\n"));
562 socket_address_ = service_runtime_->default_socket_address();
563 PLUGIN_PRINTF((" Load: established socket address %p\n",
564 static_cast<void*>(socket_address_)));
565 socket_ = service_runtime_->default_socket();
566 PLUGIN_PRINTF((" Load: established socket %p\n",
567 static_cast<void*>(socket_)));
568 // Plugin takes ownership of socket_ from service_runtime_,
569 // so we do not need to call NPN_RetainObject.
570 // Invoke the onload handler, if any.
571 RunOnloadHandler();
572 return true;
573 }
574
575 bool Plugin::LogAtServiceRuntime(int severity, nacl::string msg) {
576 return service_runtime_->Log(severity, msg);
577 }
578
579 char* Plugin::LookupArgument(const char* key) {
580 char** keys = argn();
581 for (int ii = 0, len = argc(); ii < len; ++ii) {
582 if (!strcmp(keys[ii], key)) {
583 return argv()[ii];
584 }
585 }
586 return NULL;
587 }
588
589 bool Plugin::RunOnloadHandler() {
590 BrowserInterface* browser = browser_interface();
591 const char* onload_handler = LookupArgument("onload");
592 if (onload_handler == NULL) {
593 return true;
594 }
595 return browser->EvalString(instance_id(), onload_handler);
596 }
597
598 bool Plugin::RunOnfailHandler() {
599 BrowserInterface* browser = browser_interface();
600 const char* onfail_handler = LookupArgument("onfail");
601 if (onfail_handler == NULL) {
602 return true;
603 }
604 return browser->EvalString(instance_id(), onfail_handler);
605 }
606
607 // The NaCl audio/video interface uses a global mutex to protect observed
608 // timing-sensitive accesses to the plugin's window when starting up and
609 // shutting down. Because there is a relatively complex relationship between
610 // ConnectedSocket and Plugin to synchronize accesses, this code is built in
611 // both the NPAPI and PPAPI plugins. This is unfortunate, because only
612 // the NPAPI plugin (when not used as part of the Chrome integration) actually
613 // needs the locking.
614 // TODO(sehr): move this code to somewhere in the npapi directory.
615 class GlobalVideoMutex {
616 public:
617 GlobalVideoMutex() { NaClMutexCtor(&mutex_); }
618 ~GlobalVideoMutex() { NaClMutexDtor(&mutex_); }
619 void Lock() { NaClMutexLock(&mutex_); }
620 void Unlock() { NaClMutexUnlock(&mutex_); }
621
622 private:
623 NaClMutex mutex_;
624 };
625
626 static GlobalVideoMutex g_VideoMutex;
627
628 void VideoGlobalLock() {
629 g_VideoMutex.Lock();
630 }
631
632 void VideoGlobalUnlock() {
633 g_VideoMutex.Unlock();
634 }
635
636 } // namespace plugin
OLDNEW
« no previous file with comments | « src/trusted/plugin/srpc/plugin.h ('k') | src/trusted/plugin/srpc/portable_handle.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698