| OLD | NEW |
| 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 "components/nacl/renderer/plugin/service_runtime.h" | 9 #include "components/nacl/renderer/plugin/service_runtime.h" |
| 10 | 10 |
| 11 #include <string.h> | 11 #include <string.h> |
| 12 #include <string> | 12 #include <string> |
| 13 #include <utility> | 13 #include <utility> |
| 14 | 14 |
| 15 #include "base/compiler_specific.h" | 15 #include "base/compiler_specific.h" |
| 16 #include "components/nacl/renderer/plugin/plugin.h" | 16 #include "components/nacl/renderer/plugin/plugin.h" |
| 17 #include "components/nacl/renderer/plugin/plugin_error.h" | 17 #include "components/nacl/renderer/plugin/plugin_error.h" |
| 18 #include "components/nacl/renderer/plugin/pnacl_resources.h" | |
| 19 #include "components/nacl/renderer/plugin/sel_ldr_launcher_chrome.h" | 18 #include "components/nacl/renderer/plugin/sel_ldr_launcher_chrome.h" |
| 20 #include "components/nacl/renderer/plugin/srpc_client.h" | 19 #include "components/nacl/renderer/plugin/srpc_client.h" |
| 21 #include "components/nacl/renderer/plugin/utility.h" | 20 #include "components/nacl/renderer/plugin/utility.h" |
| 22 #include "native_client/src/include/nacl_macros.h" | 21 #include "native_client/src/include/nacl_macros.h" |
| 23 #include "native_client/src/include/nacl_scoped_ptr.h" | 22 #include "native_client/src/include/nacl_scoped_ptr.h" |
| 24 #include "native_client/src/include/portability_io.h" | 23 #include "native_client/src/include/portability_io.h" |
| 25 #include "native_client/src/include/portability_string.h" | 24 #include "native_client/src/include/portability_string.h" |
| 26 #include "native_client/src/public/imc_types.h" | 25 #include "native_client/src/public/imc_types.h" |
| 27 #include "native_client/src/shared/platform/nacl_check.h" | 26 #include "native_client/src/shared/platform/nacl_check.h" |
| 28 #include "native_client/src/shared/platform/nacl_log.h" | 27 #include "native_client/src/shared/platform/nacl_log.h" |
| 29 #include "native_client/src/shared/platform/nacl_sync.h" | |
| 30 #include "native_client/src/shared/platform/nacl_sync_checked.h" | |
| 31 #include "native_client/src/shared/platform/nacl_sync_raii.h" | |
| 32 #include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h" | 28 #include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h" |
| 33 #include "native_client/src/trusted/service_runtime/nacl_error_code.h" | 29 #include "native_client/src/trusted/service_runtime/nacl_error_code.h" |
| 34 #include "ppapi/c/pp_errors.h" | 30 #include "ppapi/c/pp_errors.h" |
| 35 #include "ppapi/cpp/completion_callback.h" | 31 #include "ppapi/cpp/completion_callback.h" |
| 36 #include "ppapi/cpp/core.h" | 32 #include "ppapi/cpp/core.h" |
| 37 | 33 |
| 38 namespace plugin { | 34 namespace plugin { |
| 39 | 35 |
| 40 ServiceRuntime::ServiceRuntime(Plugin* plugin, | 36 ServiceRuntime::ServiceRuntime(Plugin* plugin, |
| 41 PP_Instance pp_instance, | 37 PP_Instance pp_instance, |
| 42 bool main_service_runtime, | 38 bool main_service_runtime, |
| 43 bool uses_nonsfi_mode) | 39 bool uses_nonsfi_mode) |
| 44 : plugin_(plugin), | 40 : plugin_(plugin), |
| 45 pp_instance_(pp_instance), | 41 pp_instance_(pp_instance), |
| 46 main_service_runtime_(main_service_runtime), | 42 main_service_runtime_(main_service_runtime), |
| 47 uses_nonsfi_mode_(uses_nonsfi_mode), | 43 uses_nonsfi_mode_(uses_nonsfi_mode), |
| 48 start_sel_ldr_done_(false), | |
| 49 sel_ldr_wait_timed_out_(false), | |
| 50 start_nexe_done_(false), | |
| 51 nexe_started_ok_(false), | |
| 52 bootstrap_channel_(NACL_INVALID_HANDLE) { | 44 bootstrap_channel_(NACL_INVALID_HANDLE) { |
| 53 NaClSrpcChannelInitialize(&command_channel_); | 45 NaClSrpcChannelInitialize(&command_channel_); |
| 54 NaClXMutexCtor(&mu_); | |
| 55 NaClXCondVarCtor(&cond_); | |
| 56 } | 46 } |
| 57 | 47 |
| 58 bool ServiceRuntime::SetupCommandChannel() { | 48 bool ServiceRuntime::SetupCommandChannel() { |
| 59 NaClLog(4, "ServiceRuntime::SetupCommand (this=%p, subprocess=%p)\n", | 49 NaClLog(4, "ServiceRuntime::SetupCommand (this=%p, subprocess=%p)\n", |
| 60 static_cast<void*>(this), | 50 static_cast<void*>(this), |
| 61 static_cast<void*>(subprocess_.get())); | 51 static_cast<void*>(subprocess_.get())); |
| 62 // Set up the bootstrap channel in our subprocess so that we can establish | 52 // Set up the bootstrap channel in our subprocess so that we can establish |
| 63 // SRPC. | 53 // SRPC. |
| 64 subprocess_->set_channel(bootstrap_channel_); | 54 subprocess_->set_channel(bootstrap_channel_); |
| 65 | 55 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 PP_FromBool(main_service_runtime_), | 90 PP_FromBool(main_service_runtime_), |
| 101 params.url.c_str(), | 91 params.url.c_str(), |
| 102 ¶ms.file_info, | 92 ¶ms.file_info, |
| 103 PP_FromBool(uses_nonsfi_mode_), | 93 PP_FromBool(uses_nonsfi_mode_), |
| 104 params.process_type, | 94 params.process_type, |
| 105 &bootstrap_channel_, | 95 &bootstrap_channel_, |
| 106 callback.pp_completion_callback()); | 96 callback.pp_completion_callback()); |
| 107 subprocess_.reset(tmp_subprocess.release()); | 97 subprocess_.reset(tmp_subprocess.release()); |
| 108 } | 98 } |
| 109 | 99 |
| 110 bool ServiceRuntime::WaitForSelLdrStart() { | |
| 111 // Time to wait on condvar (for browser to create a new sel_ldr process on | |
| 112 // our behalf). Use 6 seconds to be *fairly* conservative. | |
| 113 // | |
| 114 // On surfaway, the CallOnMainThread above may never get scheduled | |
| 115 // to unblock this condvar, or the IPC reply from the browser to renderer | |
| 116 // might get canceled/dropped. However, it is currently important to | |
| 117 // avoid waiting indefinitely because ~PnaclCoordinator will attempt to | |
| 118 // join() the PnaclTranslateThread, and the PnaclTranslateThread is waiting | |
| 119 // for the signal before exiting. | |
| 120 static int64_t const kWaitTimeMicrosecs = 6 * NACL_MICROS_PER_UNIT; | |
| 121 int64_t left_to_wait = kWaitTimeMicrosecs; | |
| 122 int64_t deadline = NaClGetTimeOfDayMicroseconds() + left_to_wait; | |
| 123 nacl::MutexLocker take(&mu_); | |
| 124 while(!start_sel_ldr_done_ && left_to_wait > 0) { | |
| 125 struct nacl_abi_timespec left_timespec; | |
| 126 left_timespec.tv_sec = left_to_wait / NACL_MICROS_PER_UNIT; | |
| 127 left_timespec.tv_nsec = | |
| 128 (left_to_wait % NACL_MICROS_PER_UNIT) * NACL_NANOS_PER_MICRO; | |
| 129 NaClXCondVarTimedWaitRelative(&cond_, &mu_, &left_timespec); | |
| 130 int64_t now = NaClGetTimeOfDayMicroseconds(); | |
| 131 left_to_wait = deadline - now; | |
| 132 } | |
| 133 if (left_to_wait <= 0) | |
| 134 sel_ldr_wait_timed_out_ = true; | |
| 135 return start_sel_ldr_done_; | |
| 136 } | |
| 137 | |
| 138 void ServiceRuntime::SignalStartSelLdrDone() { | |
| 139 nacl::MutexLocker take(&mu_); | |
| 140 start_sel_ldr_done_ = true; | |
| 141 NaClXCondVarSignal(&cond_); | |
| 142 } | |
| 143 | |
| 144 bool ServiceRuntime::SelLdrWaitTimedOut() { | |
| 145 nacl::MutexLocker take(&mu_); | |
| 146 return sel_ldr_wait_timed_out_; | |
| 147 } | |
| 148 | |
| 149 bool ServiceRuntime::WaitForNexeStart() { | |
| 150 nacl::MutexLocker take(&mu_); | |
| 151 while (!start_nexe_done_) | |
| 152 NaClXCondVarWait(&cond_, &mu_); | |
| 153 return nexe_started_ok_; | |
| 154 } | |
| 155 | |
| 156 void ServiceRuntime::SignalNexeStarted(bool ok) { | |
| 157 nacl::MutexLocker take(&mu_); | |
| 158 start_nexe_done_ = true; | |
| 159 nexe_started_ok_ = ok; | |
| 160 NaClXCondVarSignal(&cond_); | |
| 161 } | |
| 162 | |
| 163 void ServiceRuntime::StartNexe() { | 100 void ServiceRuntime::StartNexe() { |
| 164 bool ok = SetupCommandChannel(); | 101 bool ok = SetupCommandChannel(); |
| 165 if (ok) { | 102 if (ok) { |
| 166 NaClLog(4, "ServiceRuntime::StartNexe (success)\n"); | 103 NaClLog(4, "ServiceRuntime::StartNexe (success)\n"); |
| 167 } | 104 } |
| 168 // This only matters if a background thread is waiting, but we signal in all | |
| 169 // cases to simplify the code. | |
| 170 SignalNexeStarted(ok); | |
| 171 } | 105 } |
| 172 | 106 |
| 173 void ServiceRuntime::ReportLoadError(const ErrorInfo& error_info) { | 107 void ServiceRuntime::ReportLoadError(const ErrorInfo& error_info) { |
| 174 if (main_service_runtime_) { | 108 if (main_service_runtime_) { |
| 175 plugin_->ReportLoadError(error_info); | 109 plugin_->ReportLoadError(error_info); |
| 176 } | 110 } |
| 177 } | 111 } |
| 178 | 112 |
| 179 SrpcClient* ServiceRuntime::SetupAppChannel() { | 113 SrpcClient* ServiceRuntime::SetupAppChannel() { |
| 180 NaClLog(4, "ServiceRuntime::SetupAppChannel (subprocess_=%p)\n", | 114 NaClLog(4, "ServiceRuntime::SetupAppChannel (subprocess_=%p)\n", |
| 181 reinterpret_cast<void*>(subprocess_.get())); | 115 reinterpret_cast<void*>(subprocess_.get())); |
| 182 nacl::DescWrapper* connect_desc = subprocess_->socket_addr()->Connect(); | 116 nacl::DescWrapper* connect_desc = subprocess_->socket_addr()->Connect(); |
| 183 if (NULL == connect_desc) { | 117 if (NULL == connect_desc) { |
| 184 NaClLog(LOG_ERROR, "ServiceRuntime::SetupAppChannel (connect failed)\n"); | 118 NaClLog(LOG_ERROR, "ServiceRuntime::SetupAppChannel (connect failed)\n"); |
| 185 return NULL; | 119 return NULL; |
| 186 } else { | 120 } else { |
| 187 NaClLog(4, "ServiceRuntime::SetupAppChannel (conect_desc=%p)\n", | 121 NaClLog(4, "ServiceRuntime::SetupAppChannel (connect_desc=%p)\n", |
| 188 static_cast<void*>(connect_desc)); | 122 static_cast<void*>(connect_desc)); |
| 189 SrpcClient* srpc_client = SrpcClient::New(connect_desc); | 123 SrpcClient* srpc_client = SrpcClient::New(connect_desc); |
| 190 NaClLog(4, "ServiceRuntime::SetupAppChannel (srpc_client=%p)\n", | 124 NaClLog(4, "ServiceRuntime::SetupAppChannel (srpc_client=%p)\n", |
| 191 static_cast<void*>(srpc_client)); | 125 static_cast<void*>(srpc_client)); |
| 192 delete connect_desc; | 126 delete connect_desc; |
| 193 return srpc_client; | 127 return srpc_client; |
| 194 } | 128 } |
| 195 } | 129 } |
| 196 | 130 |
| 197 void ServiceRuntime::Shutdown() { | 131 void ServiceRuntime::Shutdown() { |
| 198 // Abandon callbacks, tell service threads to quit if they were | 132 // Abandon callbacks, tell service threads to quit if they were |
| 199 // blocked waiting for main thread operations to finish. Note that | 133 // blocked waiting for main thread operations to finish. Note that |
| 200 // some callbacks must still await their completion event, e.g., | 134 // some callbacks must still await their completion event, e.g., |
| 201 // CallOnMainThread must still wait for the time out, or I/O events | 135 // CallOnMainThread must still wait for the time out, or I/O events |
| 202 // must finish, so resources associated with pending events cannot | 136 // must finish, so resources associated with pending events cannot |
| 203 // be deallocated. | 137 // be deallocated. |
| 204 | 138 |
| 205 // Note that this does waitpid() to get rid of any zombie subprocess. | 139 // Note that this does waitpid() to get rid of any zombie subprocess. |
| 206 subprocess_.reset(NULL); | 140 subprocess_.reset(NULL); |
| 207 | 141 |
| 208 NaClSrpcDtor(&command_channel_); | 142 NaClSrpcDtor(&command_channel_); |
| 209 } | 143 } |
| 210 | 144 |
| 211 ServiceRuntime::~ServiceRuntime() { | 145 ServiceRuntime::~ServiceRuntime() { |
| 212 NaClLog(4, "ServiceRuntime::~ServiceRuntime (this=%p)\n", | 146 NaClLog(4, "ServiceRuntime::~ServiceRuntime (this=%p)\n", |
| 213 static_cast<void*>(this)); | 147 static_cast<void*>(this)); |
| 214 // We do this just in case Shutdown() was not called. | 148 // We do this just in case Shutdown() was not called. |
| 215 subprocess_.reset(NULL); | 149 subprocess_.reset(NULL); |
| 216 | |
| 217 NaClCondVarDtor(&cond_); | |
| 218 NaClMutexDtor(&mu_); | |
| 219 } | 150 } |
| 220 | 151 |
| 221 } // namespace plugin | 152 } // namespace plugin |
| OLD | NEW |