| Index: src/trusted/plugin/service_runtime.cc
|
| diff --git a/src/trusted/plugin/service_runtime.cc b/src/trusted/plugin/service_runtime.cc
|
| deleted file mode 100644
|
| index 1fea5de7ff355588b19a16cd2a9946b963b2d302..0000000000000000000000000000000000000000
|
| --- a/src/trusted/plugin/service_runtime.cc
|
| +++ /dev/null
|
| @@ -1,550 +0,0 @@
|
| -/*
|
| - * Copyright (c) 2011 The Native Client Authors. All rights reserved.
|
| - * Use of this source code is governed by a BSD-style license that can be
|
| - * found in the LICENSE file.
|
| - */
|
| -
|
| -#define NACL_LOG_MODULE_NAME "Plugin::ServiceRuntime"
|
| -
|
| -#include "native_client/src/trusted/plugin/service_runtime.h"
|
| -
|
| -#include <string.h>
|
| -#include <map>
|
| -#include <set>
|
| -#include <string>
|
| -#include <utility>
|
| -#include <vector>
|
| -
|
| -#include "native_client/src/include/portability_io.h"
|
| -#include "native_client/src/include/nacl_scoped_ptr.h"
|
| -#include "native_client/src/include/nacl_macros.h"
|
| -#include "native_client/src/include/nacl_string.h"
|
| -#include "native_client/src/shared/imc/nacl_imc.h"
|
| -#include "native_client/src/shared/platform/nacl_check.h"
|
| -#include "native_client/src/shared/platform/nacl_log.h"
|
| -#include "native_client/src/shared/platform/nacl_sync.h"
|
| -#include "native_client/src/shared/platform/nacl_sync_checked.h"
|
| -#include "native_client/src/shared/platform/nacl_sync_raii.h"
|
| -#include "native_client/src/shared/platform/scoped_ptr_refcount.h"
|
| -#include "native_client/src/trusted/desc/nacl_desc_imc.h"
|
| -#include "native_client/src/trusted/desc/nrd_xfer.h"
|
| -#include "native_client/src/trusted/desc/nrd_xfer_effector.h"
|
| -#include "native_client/src/trusted/handle_pass/browser_handle.h"
|
| -#include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h"
|
| -
|
| -#include "native_client/src/trusted/plugin/browser_interface.h"
|
| -#include "native_client/src/trusted/plugin/manifest.h"
|
| -#include "native_client/src/trusted/plugin/plugin.h"
|
| -#include "native_client/src/trusted/plugin/plugin_error.h"
|
| -#include "native_client/src/trusted/plugin/scriptable_handle.h"
|
| -#include "native_client/src/trusted/plugin/srpc_client.h"
|
| -#include "native_client/src/trusted/plugin/utility.h"
|
| -
|
| -#include "native_client/src/trusted/weak_ref/call_on_main_thread.h"
|
| -
|
| -#include "native_client/src/trusted/service_runtime/nacl_error_code.h"
|
| -#include "native_client/src/trusted/service_runtime/include/sys/nacl_imc_api.h"
|
| -
|
| -#include "ppapi/c/pp_errors.h"
|
| -#include "ppapi/cpp/core.h"
|
| -#include "ppapi/cpp/completion_callback.h"
|
| -
|
| -using std::vector;
|
| -
|
| -namespace plugin {
|
| -
|
| -PluginReverseInterface::PluginReverseInterface(
|
| - nacl::WeakRefAnchor* anchor,
|
| - Plugin* plugin,
|
| - pp::CompletionCallback init_done_cb)
|
| - : anchor_(anchor),
|
| - plugin_(plugin),
|
| - shutting_down_(false),
|
| - init_done_cb_(init_done_cb) {
|
| - NaClXMutexCtor(&mu_);
|
| - NaClXCondVarCtor(&cv_);
|
| -}
|
| -
|
| -PluginReverseInterface::~PluginReverseInterface() {
|
| - NaClCondVarDtor(&cv_);
|
| - NaClMutexDtor(&mu_);
|
| -}
|
| -
|
| -void PluginReverseInterface::ShutDown() {
|
| - nacl::MutexLocker take(&mu_);
|
| - shutting_down_ = true;
|
| - NaClXCondVarBroadcast(&cv_);
|
| -}
|
| -
|
| -void PluginReverseInterface::Log(nacl::string message) {
|
| - LogToJavaScriptConsoleResource* continuation =
|
| - new LogToJavaScriptConsoleResource(message);
|
| - CHECK(continuation != NULL);
|
| - NaClLog(4, "PluginReverseInterface::Log(%s)\n", message.c_str());
|
| - plugin::WeakRefCallOnMainThread(
|
| - anchor_,
|
| - 0, /* delay in ms */
|
| - this,
|
| - &plugin::PluginReverseInterface::Log_MainThreadContinuation,
|
| - continuation);
|
| -}
|
| -
|
| -void PluginReverseInterface::StartupInitializationComplete() {
|
| - NaClLog(0, "PluginReverseInterface::StartupInitializationComplete\n");
|
| - if (init_done_cb_.pp_completion_callback().func != NULL) {
|
| - NaClLog(0,
|
| - "PluginReverseInterface::StartupInitializationComplete:"
|
| - " invoking CB\n");
|
| - pp::Module::Get()->core()->CallOnMainThread(0, init_done_cb_, PP_OK);
|
| - } else {
|
| - NaClLog(0,
|
| - "PluginReverseInterface::StartupInitializationComplete:"
|
| - " init_done_cb_ not valid, skipping.\n");
|
| - }
|
| -}
|
| -
|
| -void PluginReverseInterface::Log_MainThreadContinuation(
|
| - LogToJavaScriptConsoleResource* p,
|
| - int32_t err) {
|
| - UNREFERENCED_PARAMETER(err);
|
| - NaClLog(4,
|
| - "PluginReverseInterface::Log_MainThreadContinuation(%s)\n",
|
| - p->message.c_str());
|
| - plugin_->browser_interface()->AddToConsole(static_cast<Plugin*>(plugin_),
|
| - p->message);
|
| -}
|
| -
|
| -bool PluginReverseInterface::EnumerateManifestKeys(
|
| - std::set<nacl::string>* out_keys) {
|
| - Manifest const* mp = plugin_->manifest();
|
| -
|
| - if (!mp->GetFileKeys(out_keys)) {
|
| - return false;
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -// TODO(bsy): OpenManifestEntry should use the manifest to ResolveKey
|
| -// and invoke StreamAsFile with a completion callback that invokes
|
| -// GetPOSIXFileDesc.
|
| -bool PluginReverseInterface::OpenManifestEntry(nacl::string url_key,
|
| - int32_t* out_desc) {
|
| - ErrorInfo error_info;
|
| - bool is_portable = false;
|
| - bool op_complete = false; // NB: mu_ and cv_ also controls access to this!
|
| - OpenManifestEntryResource* to_open =
|
| - new OpenManifestEntryResource(url_key, out_desc,
|
| - &error_info, &is_portable, &op_complete);
|
| - CHECK(to_open != NULL);
|
| - NaClLog(4, "PluginReverseInterface::OpenManifestEntry: %s\n",
|
| - url_key.c_str());
|
| - // This assumes we are not on the main thread. If false, we deadlock.
|
| - plugin::WeakRefCallOnMainThread(
|
| - anchor_,
|
| - 0,
|
| - this,
|
| - &plugin::PluginReverseInterface::OpenManifestEntry_MainThreadContinuation,
|
| - to_open);
|
| - NaClLog(4,
|
| - "PluginReverseInterface::OpenManifestEntry:"
|
| - " waiting on main thread\n");
|
| - bool shutting_down;
|
| - do {
|
| - nacl::MutexLocker take(&mu_);
|
| - for (;;) {
|
| - NaClLog(4,
|
| - "PluginReverseInterface::OpenManifestEntry:"
|
| - " got lock, checking shutdown and completion: (%s, %s)\n",
|
| - shutting_down_ ? "yes" : "no",
|
| - op_complete ? "yes" : "no");
|
| - shutting_down = shutting_down_;
|
| - if (op_complete || shutting_down) {
|
| - NaClLog(4,
|
| - "PluginReverseInterface::OpenManifestEntry:"
|
| - " done!\n");
|
| - break;
|
| - }
|
| - NaClXCondVarWait(&cv_, &mu_);
|
| - }
|
| - } while (0);
|
| - if (shutting_down) {
|
| - NaClLog(4,
|
| - "PluginReverseInterface::OpenManifestEntry:"
|
| - " plugin is shutting down\n");
|
| - return false;
|
| - }
|
| - // out_desc has the returned descriptor if successful, else -1.
|
| -
|
| - // The caller is responsible for not closing *out_desc. If it is
|
| - // closed prematurely, then another open could re-use the OS
|
| - // descriptor, confusing the opened_ map. If the caller is going to
|
| - // want to make a NaClDesc object and transfer it etc., then the
|
| - // caller should DUP the descriptor (but remember the original
|
| - // value) for use by the NaClDesc object, which closes when the
|
| - // object is destroyed.
|
| - NaClLog(4,
|
| - "PluginReverseInterface::OpenManifestEntry:"
|
| - " *out_desc = %d\n",
|
| - *out_desc);
|
| - if (*out_desc == -1) {
|
| - // TODO(bsy,ncbray): what else should we do with the error? This
|
| - // is a runtime error that may simply be a programming error in
|
| - // the untrusted code, or it may be something else wrong w/ the
|
| - // manifest.
|
| - NaClLog(4,
|
| - "OpenManifestEntry: failed for key %s, code %d (%s)\n",
|
| - url_key.c_str(),
|
| - error_info.error_code(),
|
| - error_info.message().c_str());
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation(
|
| - OpenManifestEntryResource* p,
|
| - int32_t err) {
|
| - OpenManifestEntryResource *open_cont;
|
| - UNREFERENCED_PARAMETER(err);
|
| - // CallOnMainThread continuations always called with err == PP_OK.
|
| -
|
| - NaClLog(4, "Entered OpenManifestEntry_MainThreadContinuation\n");
|
| -
|
| - std::string mapped_url;
|
| - if (!plugin_->manifest()->ResolveKey(p->url, &mapped_url,
|
| - p->error_info, p->is_portable)) {
|
| - NaClLog(4, "OpenManifestEntry_MainThreadContinuation: ResolveKey failed\n");
|
| - // Failed, and error_info has the details on what happened. Wake
|
| - // up requesting thread -- we are done.
|
| - nacl::MutexLocker take(&mu_);
|
| - *p->op_complete_ptr = true; // done...
|
| - *p->out_desc = -1; // but failed.
|
| - NaClXCondVarBroadcast(&cv_);
|
| - return;
|
| - }
|
| - NaClLog(4,
|
| - "OpenManifestEntry_MainThreadContinuation: ResolveKey: %s -> %s\n",
|
| - p->url.c_str(), mapped_url.c_str());
|
| -
|
| - open_cont = new OpenManifestEntryResource(*p); // copy ctor!
|
| - CHECK(open_cont != NULL);
|
| - open_cont->url = mapped_url;
|
| - pp::CompletionCallback stream_cc = WeakRefNewCallback(
|
| - anchor_,
|
| - this,
|
| - &PluginReverseInterface::StreamAsFile_MainThreadContinuation,
|
| - open_cont);
|
| - if (!plugin_->StreamAsFile(mapped_url, stream_cc.pp_completion_callback())) {
|
| - NaClLog(4,
|
| - "OpenManifestEntry_MainThreadContinuation: StreamAsFile failed\n");
|
| - nacl::MutexLocker take(&mu_);
|
| - *p->op_complete_ptr = true; // done...
|
| - *p->out_desc = -1; // but failed.
|
| - p->error_info->SetReport(ERROR_MANIFEST_OPEN,
|
| - "ServiceRuntime: StreamAsFile failed");
|
| - NaClXCondVarBroadcast(&cv_);
|
| - return;
|
| - }
|
| - NaClLog(4,
|
| - "OpenManifestEntry_MainThreadContinuation: StreamAsFile okay\n");
|
| - // p is deleted automatically
|
| -}
|
| -
|
| -void PluginReverseInterface::StreamAsFile_MainThreadContinuation(
|
| - OpenManifestEntryResource* p,
|
| - int32_t result) {
|
| - NaClLog(4,
|
| - "Entered StreamAsFile_MainThreadContinuation\n");
|
| -
|
| - nacl::MutexLocker take(&mu_);
|
| - if (result == PP_OK) {
|
| - NaClLog(4, "StreamAsFile_MainThreadContinuation: GetPOSIXFileDesc(%s)\n",
|
| - p->url.c_str());
|
| - *p->out_desc = plugin_->GetPOSIXFileDesc(p->url);
|
| - NaClLog(4,
|
| - "StreamAsFile_MainThreadContinuation: PP_OK, desc %d\n",
|
| - *p->out_desc);
|
| - } else {
|
| - NaClLog(4,
|
| - "StreamAsFile_MainThreadContinuation: !PP_OK, setting desc -1\n");
|
| - *p->out_desc = -1;
|
| - p->error_info->SetReport(ERROR_MANIFEST_OPEN,
|
| - "Plugin StreamAsFile failed at callback");
|
| - }
|
| - *p->op_complete_ptr = true;
|
| - NaClXCondVarBroadcast(&cv_);
|
| -}
|
| -
|
| -bool PluginReverseInterface::CloseManifestEntry(int32_t desc) {
|
| - bool op_complete;
|
| - bool op_result;
|
| - CloseManifestEntryResource* to_close =
|
| - new CloseManifestEntryResource(desc, &op_complete, &op_result);
|
| -
|
| - bool shutting_down;
|
| - plugin::WeakRefCallOnMainThread(
|
| - anchor_,
|
| - 0,
|
| - this,
|
| - &plugin::PluginReverseInterface::
|
| - CloseManifestEntry_MainThreadContinuation,
|
| - to_close);
|
| - // wait for completion or surf-away.
|
| - do {
|
| - nacl::MutexLocker take(&mu_);
|
| - for (;;) {
|
| - shutting_down = shutting_down_;
|
| - if (op_complete || shutting_down) {
|
| - break;
|
| - }
|
| - NaClXCondVarWait(&cv_, &mu_);
|
| - }
|
| - } while (0);
|
| -
|
| - if (shutting_down) return false;
|
| - // op_result true if close was successful; false otherwise (e.g., bad desc).
|
| - return op_result;
|
| -}
|
| -
|
| -void PluginReverseInterface::CloseManifestEntry_MainThreadContinuation(
|
| - CloseManifestEntryResource* cls,
|
| - int32_t err) {
|
| - UNREFERENCED_PARAMETER(err);
|
| -
|
| - nacl::MutexLocker take(&mu_);
|
| - // TODO(bsy): once the plugin has a reliable way to report that the
|
| - // file usage is done -- and sel_ldr uses this RPC call -- we should
|
| - // tell the plugin that the associated resources can be freed.
|
| - *cls->op_result_ptr = true;
|
| - *cls->op_complete_ptr = true;
|
| - NaClXCondVarBroadcast(&cv_);
|
| - // cls automatically deleted
|
| -}
|
| -
|
| -ServiceRuntime::ServiceRuntime(Plugin* plugin,
|
| - pp::CompletionCallback init_done_cb)
|
| - : plugin_(plugin),
|
| - browser_interface_(plugin->browser_interface()),
|
| - reverse_service_(NULL),
|
| - subprocess_(NULL),
|
| - async_receive_desc_(NULL),
|
| - async_send_desc_(NULL),
|
| - anchor_(new nacl::WeakRefAnchor()),
|
| - rev_interface_(new PluginReverseInterface(anchor_, plugin,
|
| - init_done_cb)) {
|
| - NaClSrpcChannelInitialize(&command_channel_);
|
| -}
|
| -
|
| -bool ServiceRuntime::InitCommunication(nacl::DescWrapper* nacl_desc,
|
| - ErrorInfo* error_info) {
|
| - PLUGIN_PRINTF(("ServiceRuntime::InitCommunication"
|
| - " (this=%p, subprocess=%p)\n",
|
| - static_cast<void*>(this),
|
| - static_cast<void*>(subprocess_.get())));
|
| - // Create the command channel to the sel_ldr and load the nexe from nacl_desc.
|
| - if (!subprocess_->SetupCommandAndLoad(&command_channel_, nacl_desc)) {
|
| - error_info->SetReport(ERROR_SEL_LDR_COMMUNICATION_CMD_CHANNEL,
|
| - "ServiceRuntime: command channel creation failed");
|
| - return false;
|
| - }
|
| - // Hook up the reverse service channel. We are the IMC client, but
|
| - // provide SRPC service.
|
| - NaClDesc* out_conn_cap;
|
| - NaClSrpcResultCodes rpc_result =
|
| - NaClSrpcInvokeBySignature(&command_channel_,
|
| - "reverse_setup::h",
|
| - &out_conn_cap);
|
| -
|
| - if (NACL_SRPC_RESULT_OK != rpc_result) {
|
| - error_info->SetReport(ERROR_SEL_LDR_COMMUNICATION_REV_SETUP,
|
| - "ServiceRuntime: reverse setup rpc failed");
|
| - return false;
|
| - }
|
| - // Get connection capability to service runtime where the IMC
|
| - // server/SRPC client is waiting for a rendezvous.
|
| - PLUGIN_PRINTF(("ServiceRuntime: got 0x%"NACL_PRIxPTR"\n",
|
| - (uintptr_t) out_conn_cap));
|
| - nacl::DescWrapper* conn_cap = plugin_->wrapper_factory()->MakeGenericCleanup(
|
| - out_conn_cap);
|
| - if (conn_cap == NULL) {
|
| - error_info->SetReport(ERROR_SEL_LDR_COMMUNICATION_WRAPPER,
|
| - "ServiceRuntime: wrapper allocation failure");
|
| - return false;
|
| - }
|
| - out_conn_cap = NULL; // ownership passed
|
| - reverse_service_ = new nacl::ReverseService(conn_cap, rev_interface_->Ref());
|
| - if (!reverse_service_->Start()) {
|
| - error_info->SetReport(ERROR_SEL_LDR_COMMUNICATION_REV_SERVICE,
|
| - "ServiceRuntime: starting reverse services failed");
|
| - return false;
|
| - }
|
| -
|
| -#if NACL_WINDOWS && !defined(NACL_STANDALONE)
|
| - // Establish the communication for handle passing protocol
|
| - struct NaClDesc* desc = NaClHandlePassBrowserGetSocketAddress();
|
| -
|
| - DWORD my_pid = GetCurrentProcessId();
|
| - nacl::Handle my_handle = GetCurrentProcess();
|
| - nacl::Handle my_handle_in_selldr;
|
| -
|
| - if (!DuplicateHandle(GetCurrentProcess(),
|
| - my_handle,
|
| - subprocess_->child_process(),
|
| - &my_handle_in_selldr,
|
| - PROCESS_DUP_HANDLE,
|
| - FALSE,
|
| - 0)) {
|
| - error_info->SetReport(ERROR_SEL_LDR_HANDLE_PASSING,
|
| - "ServiceRuntime: failed handle passing protocol");
|
| - return false;
|
| - }
|
| -
|
| - rpc_result =
|
| - NaClSrpcInvokeBySignature(&command_channel_,
|
| - "init_handle_passing:hii:",
|
| - desc,
|
| - my_pid,
|
| - reinterpret_cast<int>(my_handle_in_selldr));
|
| -
|
| - if (NACL_SRPC_RESULT_OK != rpc_result) {
|
| - error_info->SetReport(ERROR_SEL_LDR_HANDLE_PASSING,
|
| - "ServiceRuntime: failed handle passing protocol");
|
| - return false;
|
| - }
|
| -#endif
|
| - // start the module. otherwise we cannot connect for multimedia
|
| - // subsystem since that is handled by user-level code (not secure!)
|
| - // in libsrpc.
|
| - int load_status = -1;
|
| - rpc_result =
|
| - NaClSrpcInvokeBySignature(&command_channel_,
|
| - "start_module::i",
|
| - &load_status);
|
| -
|
| - if (NACL_SRPC_RESULT_OK != rpc_result) {
|
| - error_info->SetReport(ERROR_SEL_LDR_START_MODULE,
|
| - "ServiceRuntime: could not start nacl module");
|
| - return false;
|
| - }
|
| - PLUGIN_PRINTF(("ServiceRuntime::InitCommunication (load_status=%d)\n",
|
| - load_status));
|
| - plugin_->ReportSelLdrLoadStatus(load_status);
|
| - if (LOAD_OK != load_status) {
|
| - error_info->SetReport(
|
| - ERROR_SEL_LDR_START_STATUS,
|
| - NaClErrorString(static_cast<NaClErrorCode>(load_status)));
|
| - return false;
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -bool ServiceRuntime::Start(nacl::DescWrapper* nacl_desc,
|
| - ErrorInfo* error_info) {
|
| - PLUGIN_PRINTF(("ServiceRuntime::Start (nacl_desc=%p)\n",
|
| - reinterpret_cast<void*>(nacl_desc)));
|
| -
|
| - nacl::scoped_ptr<nacl::SelLdrLauncher>
|
| - tmp_subprocess(new(std::nothrow) nacl::SelLdrLauncher());
|
| - if (NULL == tmp_subprocess.get()) {
|
| - PLUGIN_PRINTF(("ServiceRuntime::Start (subprocess create failed)\n"));
|
| - error_info->SetReport(ERROR_SEL_LDR_CREATE_LAUNCHER,
|
| - "ServiceRuntime: failed to create sel_ldr launcher");
|
| - return false;
|
| - }
|
| - nacl::Handle sockets[3];
|
| - if (!tmp_subprocess->Start(NACL_ARRAY_SIZE(sockets), sockets)) {
|
| - PLUGIN_PRINTF(("ServiceRuntime::Start (start failed)\n"));
|
| - error_info->SetReport(ERROR_SEL_LDR_LAUNCH,
|
| - "ServiceRuntime: failed to start");
|
| - return false;
|
| - }
|
| -
|
| - async_receive_desc_.reset(
|
| - plugin()->wrapper_factory()->MakeImcSock(sockets[1]));
|
| - async_send_desc_.reset(plugin()->wrapper_factory()->MakeImcSock(sockets[2]));
|
| -
|
| - subprocess_.reset(tmp_subprocess.release());
|
| - if (!InitCommunication(nacl_desc, error_info)) {
|
| - subprocess_.reset(NULL);
|
| - return false;
|
| - }
|
| -
|
| - PLUGIN_PRINTF(("ServiceRuntime::Start (return 1)\n"));
|
| - return true;
|
| -}
|
| -
|
| -SrpcClient* ServiceRuntime::SetupAppChannel() {
|
| - PLUGIN_PRINTF(("ServiceRuntime::SetupAppChannel (subprocess_=%p)\n",
|
| - reinterpret_cast<void*>(subprocess_.get())));
|
| - nacl::DescWrapper* connect_desc = subprocess_->socket_addr()->Connect();
|
| - if (NULL == connect_desc) {
|
| - PLUGIN_PRINTF(("ServiceRuntime::SetupAppChannel (connect failed)\n"));
|
| - return NULL;
|
| - } else {
|
| - PLUGIN_PRINTF(("ServiceRuntime::SetupAppChannel (conect_desc=%p)\n",
|
| - static_cast<void*>(connect_desc)));
|
| - SrpcClient* srpc_client = SrpcClient::New(plugin(), connect_desc);
|
| - PLUGIN_PRINTF(("ServiceRuntime::SetupAppChannel (srpc_client=%p)\n",
|
| - static_cast<void*>(srpc_client)));
|
| - return srpc_client;
|
| - }
|
| -}
|
| -
|
| -bool ServiceRuntime::Kill() {
|
| - return subprocess_->KillChildProcess();
|
| -}
|
| -
|
| -bool ServiceRuntime::Log(int severity, nacl::string msg) {
|
| - NaClSrpcResultCodes rpc_result =
|
| - NaClSrpcInvokeBySignature(&command_channel_,
|
| - "log:is:",
|
| - severity,
|
| - strdup(msg.c_str()));
|
| - return (NACL_SRPC_RESULT_OK == rpc_result);
|
| -}
|
| -
|
| -void ServiceRuntime::Shutdown() {
|
| - if (subprocess_ != NULL) {
|
| - Kill();
|
| - }
|
| - rev_interface_->ShutDown();
|
| - anchor_->Abandon();
|
| - // Abandon callbacks, tell service threads to quit if they were
|
| - // blocked waiting for main thread operations to finish. Note that
|
| - // some callbacks must still await their completion event, e.g.,
|
| - // CallOnMainThread must still wait for the time out, or I/O events
|
| - // must finish, so resources associated with pending events cannot
|
| - // be deallocated.
|
| -
|
| - // Note that this does waitpid() to get rid of any zombie subprocess.
|
| - subprocess_.reset(NULL);
|
| -
|
| - NaClSrpcDtor(&command_channel_);
|
| -
|
| - // subprocess_ killed, but threads waiting on messages from the
|
| - // service runtime may not have noticed yet. The low-level
|
| - // NaClSimpleRevService code takes care to refcount the data objects
|
| - // that it needs, and reverse_service_ is also refcounted. We wait
|
| - // for the service threads to get their EOF indications.
|
| - if (reverse_service_ != NULL) {
|
| - reverse_service_->WaitForServiceThreadsToExit();
|
| - reverse_service_->Unref();
|
| - reverse_service_ = NULL;
|
| - }
|
| -}
|
| -
|
| -ServiceRuntime::~ServiceRuntime() {
|
| - PLUGIN_PRINTF(("ServiceRuntime::~ServiceRuntime (this=%p)\n",
|
| - static_cast<void*>(this)));
|
| - // We do this just in case Shutdown() was not called.
|
| - subprocess_.reset(NULL);
|
| - if (reverse_service_ != NULL) {
|
| - reverse_service_->Unref();
|
| - }
|
| -
|
| - rev_interface_->Unref();
|
| -
|
| - anchor_->Unref();
|
| -}
|
| -
|
| -} // namespace plugin
|
|
|