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

Side by Side Diff: components/nacl/renderer/plugin/plugin.cc

Issue 1128943003: Move PNaCl process startup back to the main thread. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: remove unused field Created 5 years, 7 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
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 "components/nacl/renderer/plugin/plugin.h" 5 #include "components/nacl/renderer/plugin/plugin.h"
6 6
7 #include <sys/stat.h> 7 #include <sys/stat.h>
8 #include <sys/types.h> 8 #include <sys/types.h>
9 9
10 #include <string> 10 #include <string>
(...skipping 20 matching lines...) Expand all
31 static_cast<void*>(this))); 31 static_cast<void*>(this)));
32 32
33 // Shut down service runtime. This must be done before all other calls so 33 // Shut down service runtime. This must be done before all other calls so
34 // they don't block forever when waiting for the upcall thread to exit. 34 // they don't block forever when waiting for the upcall thread to exit.
35 main_subprocess_.Shutdown(); 35 main_subprocess_.Shutdown();
36 36
37 PLUGIN_PRINTF(("Plugin::ShutDownSubprocess (this=%p, return)\n", 37 PLUGIN_PRINTF(("Plugin::ShutDownSubprocess (this=%p, return)\n",
38 static_cast<void*>(this))); 38 static_cast<void*>(this)));
39 } 39 }
40 40
41 bool Plugin::LoadHelperNaClModuleInternal(NaClSubprocess* subprocess, 41 void Plugin::StartSelLdr(ServiceRuntime* service_runtime,
42 const SelLdrStartParams& params) { 42 const SelLdrStartParams& params,
43 CHECK(!pp::Module::Get()->core()->IsMainThread()); 43 pp::CompletionCallback callback) {
44 ServiceRuntime* service_runtime =
45 new ServiceRuntime(this,
46 pp_instance(),
47 false, // No main_service_runtime.
48 false); // No non-SFI mode (i.e. in SFI-mode).
49
50 // Now start the SelLdr instance. This must be created on the main thread.
51 bool service_runtime_started = false;
52 pp::CompletionCallback sel_ldr_callback =
53 callback_factory_.NewCallback(&Plugin::SignalStartSelLdrDone,
54 &service_runtime_started,
55 service_runtime);
56 pp::CompletionCallback callback =
57 callback_factory_.NewCallback(&Plugin::StartSelLdrOnMainThread,
58 service_runtime, params,
59 sel_ldr_callback);
60 pp::Module::Get()->core()->CallOnMainThread(0, callback, 0);
61 if (!service_runtime->WaitForSelLdrStart()) {
62 PLUGIN_PRINTF(("Plugin::LoadHelperNaClModule "
63 "WaitForSelLdrStart timed out!\n"));
64 service_runtime->Shutdown();
65 // Don't delete service_runtime here; it could still be used by the pending
66 // SignalStartSelLdrDone callback.
67 return false;
68 }
69 PLUGIN_PRINTF(("Plugin::LoadHelperNaClModule (service_runtime_started=%d)\n",
70 service_runtime_started));
71 if (!service_runtime_started) {
72 service_runtime->Shutdown();
73 delete service_runtime;
74 return false;
75 }
76
77 // Now actually start the nexe.
78 //
79 // We can't use pp::BlockUntilComplete() inside an in-process plugin, so we
80 // have to roll our own blocking logic, similar to WaitForSelLdrStart()
81 // above, except without timeout logic.
82 pp::Module::Get()->core()->CallOnMainThread(
83 0,
84 callback_factory_.NewCallback(&Plugin::StartNexe, service_runtime));
85 if (!service_runtime->WaitForNexeStart()) {
86 service_runtime->Shutdown();
87 delete service_runtime;
88 return false;
89 }
90 subprocess->set_service_runtime(service_runtime);
91 return true;
92 }
93
94 void Plugin::StartSelLdrOnMainThread(int32_t pp_error,
95 ServiceRuntime* service_runtime,
96 const SelLdrStartParams& params,
97 pp::CompletionCallback callback) {
98 CHECK(pp_error == PP_OK);
99 service_runtime->StartSelLdr(params, callback); 44 service_runtime->StartSelLdr(params, callback);
100 } 45 }
101 46
102 void Plugin::SignalStartSelLdrDone(int32_t pp_error,
103 bool* started,
104 ServiceRuntime* service_runtime) {
105 if (service_runtime->SelLdrWaitTimedOut()) {
106 delete service_runtime;
107 } else {
108 *started = (pp_error == PP_OK);
109 service_runtime->SignalStartSelLdrDone();
110 }
111 }
112
113 void Plugin::LoadNaClModule(PP_NaClFileInfo file_info, 47 void Plugin::LoadNaClModule(PP_NaClFileInfo file_info,
114 bool uses_nonsfi_mode, 48 bool uses_nonsfi_mode,
115 PP_NaClAppProcessType process_type) { 49 PP_NaClAppProcessType process_type) {
116 CHECK(pp::Module::Get()->core()->IsMainThread()); 50 CHECK(pp::Module::Get()->core()->IsMainThread());
117 // Before forking a new sel_ldr process, ensure that we do not leak 51 // Before forking a new sel_ldr process, ensure that we do not leak
118 // the ServiceRuntime object for an existing subprocess, and that any 52 // the ServiceRuntime object for an existing subprocess, and that any
119 // associated listener threads do not go unjoined because if they 53 // associated listener threads do not go unjoined because if they
120 // outlive the Plugin object, they will not be memory safe. 54 // outlive the Plugin object, they will not be memory safe.
121 ShutDownSubprocesses(); 55 ShutDownSubprocesses();
122 pp::Var manifest_base_url = 56 pp::Var manifest_base_url =
(...skipping 12 matching lines...) Expand all
135 PP_NACL_ERROR_SEL_LDR_INIT, 69 PP_NACL_ERROR_SEL_LDR_INIT,
136 "sel_ldr init failure " + main_subprocess_.description()); 70 "sel_ldr init failure " + main_subprocess_.description());
137 ReportLoadError(error_info); 71 ReportLoadError(error_info);
138 return; 72 return;
139 } 73 }
140 74
141 // We don't take any action once nexe loading has completed, so pass an empty 75 // We don't take any action once nexe loading has completed, so pass an empty
142 // callback here for |callback|. 76 // callback here for |callback|.
143 pp::CompletionCallback callback = callback_factory_.NewCallback( 77 pp::CompletionCallback callback = callback_factory_.NewCallback(
144 &Plugin::StartNexe, service_runtime); 78 &Plugin::StartNexe, service_runtime);
145 StartSelLdrOnMainThread( 79 StartSelLdr(service_runtime, params, callback);
146 static_cast<int32_t>(PP_OK), service_runtime, params, callback);
147 } 80 }
148 81
149 void Plugin::StartNexe(int32_t pp_error, ServiceRuntime* service_runtime) { 82 void Plugin::StartNexe(int32_t pp_error, ServiceRuntime* service_runtime) {
150 CHECK(pp::Module::Get()->core()->IsMainThread()); 83 CHECK(pp::Module::Get()->core()->IsMainThread());
151 if (pp_error != PP_OK) 84 if (pp_error != PP_OK)
152 return; 85 return;
153 service_runtime->StartNexe(); 86 service_runtime->StartNexe();
154 } 87 }
155 88
156 NaClSubprocess* Plugin::LoadHelperNaClModule(const std::string& helper_url, 89 void Plugin::LoadHelperNaClModule(const std::string& helper_url,
157 PP_NaClFileInfo file_info, 90 PP_NaClFileInfo file_info,
158 ErrorInfo* error_info) { 91 NaClSubprocess* subprocess_to_init,
159 nacl::scoped_ptr<NaClSubprocess> nacl_subprocess( 92 pp::CompletionCallback callback) {
160 new NaClSubprocess("helper module", NULL, NULL)); 93 CHECK(pp::Module::Get()->core()->IsMainThread());
161 if (NULL == nacl_subprocess.get()) {
162 error_info->SetReport(PP_NACL_ERROR_SEL_LDR_INIT,
163 "unable to allocate helper subprocess.");
164 return NULL;
165 }
166
167 // Do not report UMA stats for translator-related nexes. 94 // Do not report UMA stats for translator-related nexes.
168 // TODO(sehr): define new UMA stats for translator related nexe events. 95 // TODO(sehr): define new UMA stats for translator related nexe events.
169 // NOTE: The PNaCl translator nexes are not built to use the IRT. This is
170 // done to save on address space and swap space.
171 SelLdrStartParams params(helper_url, 96 SelLdrStartParams params(helper_url,
172 file_info, 97 file_info,
173 PP_PNACL_TRANSLATOR_PROCESS_TYPE); 98 PP_PNACL_TRANSLATOR_PROCESS_TYPE);
99 ServiceRuntime* service_runtime =
100 new ServiceRuntime(this, pp_instance(),
101 false, // Not main_service_runtime.
102 false); // No non-SFI mode (i.e. in SFI-mode).
103 subprocess_to_init->set_service_runtime(service_runtime);
104 pp::CompletionCallback sel_ldr_callback = callback_factory_.NewCallback(
105 &Plugin::StartHelperNexe, subprocess_to_init, callback);
106 StartSelLdr(service_runtime, params, sel_ldr_callback);
107 }
174 108
175 // Helper NaCl modules always use the PNaCl manifest, as there is no 109 void Plugin::StartHelperNexe(int32_t pp_error,
176 // corresponding NMF. 110 NaClSubprocess* subprocess_to_init,
177 if (!LoadHelperNaClModuleInternal(nacl_subprocess.get(), params)) 111 pp::CompletionCallback callback) {
178 return NULL; 112 CHECK(pp::Module::Get()->core()->IsMainThread());
179 113 if (pp_error != PP_OK) {
180 // We can block here in StartSrpcServices, since helper NaCl 114 callback.RunAndClear(pp_error);
181 // modules are spawned from a private thread. 115 return;
182 //
183 // TODO(bsy): if helper module crashes, we should abort.
184 // crash_cb is not used here, so we are relying on crashes
185 // being detected in StartSrpcServices or later.
186 //
187 // NB: More refactoring might be needed, however, if helper
188 // NaCl modules have their own manifest. Currently the
189 // manifest is a per-plugin-instance object, not a per
190 // NaClSubprocess object.
191 if (!nacl_subprocess->StartSrpcServices()) {
192 error_info->SetReport(PP_NACL_ERROR_SRPC_CONNECTION_FAIL,
193 "SRPC connection failure for " +
194 nacl_subprocess->description());
195 return NULL;
196 } 116 }
197 117 // TODO(jvoung): This operations blocks. That's bad because this is the
Derek Schuff 2015/05/08 22:45:59 this operation, or these operations
jvoung (off chromium) 2015/05/08 23:59:31 Done.
198 PLUGIN_PRINTF(("Plugin::LoadHelperNaClModule (%s, %s)\n", 118 // main thread. However, we could make it so that StartHelperNexe isn't
199 helper_url.c_str(), 119 // called until the blocking is minimized. There is a hook in
200 nacl_subprocess.get()->detailed_description().c_str())); 120 // sel_main_chrome which indicates when the nexe load is done. If we hook
201 121 // up that hook to StartSelLdr's callback, then we'll only
202 return nacl_subprocess.release(); 122 // call StartNexe once the nexe load is done instead of blocking here
123 // until the nexe load is done.
124 subprocess_to_init->service_runtime()->StartNexe();
125 callback.RunAndClear(PP_OK);
203 } 126 }
204 127
205 // All failures of this function will show up as "Missing Plugin-in", so 128 // All failures of this function will show up as "Missing Plugin-in", so
206 // there is no need to log to JS console that there was an initialization 129 // there is no need to log to JS console that there was an initialization
207 // failure. Note that module loading functions will log their own errors. 130 // failure. Note that module loading functions will log their own errors.
208 bool Plugin::Init(uint32_t argc, const char* argn[], const char* argv[]) { 131 bool Plugin::Init(uint32_t argc, const char* argn[], const char* argv[]) {
209 nacl_interface_->InitializePlugin(pp_instance(), argc, argn, argv); 132 nacl_interface_->InitializePlugin(pp_instance(), argc, argn, argv);
210 wrapper_factory_ = new nacl::DescWrapperFactory(); 133 wrapper_factory_ = new nacl::DescWrapperFactory();
211 pp::CompletionCallback open_cb = 134 pp::CompletionCallback open_cb =
212 callback_factory_.NewCallback(&Plugin::NaClManifestFileDidOpen); 135 callback_factory_.NewCallback(&Plugin::NaClManifestFileDidOpen);
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 } 264 }
342 } 265 }
343 266
344 void Plugin::ReportLoadError(const ErrorInfo& error_info) { 267 void Plugin::ReportLoadError(const ErrorInfo& error_info) {
345 nacl_interface_->ReportLoadError(pp_instance(), 268 nacl_interface_->ReportLoadError(pp_instance(),
346 error_info.error_code(), 269 error_info.error_code(),
347 error_info.message().c_str()); 270 error_info.message().c_str());
348 } 271 }
349 272
350 } // namespace plugin 273 } // namespace plugin
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698