| Index: chromeos/process_proxy/process_proxy_registry.cc
|
| diff --git a/chromeos/process_proxy/process_proxy_registry.cc b/chromeos/process_proxy/process_proxy_registry.cc
|
| index aa2e9d829519b1a5c567a44bbe3e669a682e6d16..3619720c3d64d80a2d5e1d406dc606159c403b03 100644
|
| --- a/chromeos/process_proxy/process_proxy_registry.cc
|
| +++ b/chromeos/process_proxy/process_proxy_registry.cc
|
| @@ -13,15 +13,12 @@ namespace {
|
| const char kWatcherThreadName[] = "ProcessWatcherThread";
|
|
|
| const char kStdoutOutputType[] = "stdout";
|
| -const char kStderrOutputType[] = "stderr";
|
| const char kExitOutputType[] = "exit";
|
|
|
| const char* ProcessOutputTypeToString(ProcessOutputType type) {
|
| switch (type) {
|
| case PROCESS_OUTPUT_TYPE_OUT:
|
| return kStdoutOutputType;
|
| - case PROCESS_OUTPUT_TYPE_ERR:
|
| - return kStderrOutputType;
|
| case PROCESS_OUTPUT_TYPE_EXIT:
|
| return kExitOutputType;
|
| default:
|
| @@ -40,7 +37,7 @@ ProcessProxyRegistry::ProcessProxyInfo::ProcessProxyInfo() {
|
| ProcessProxyRegistry::ProcessProxyInfo::ProcessProxyInfo(
|
| const ProcessProxyInfo& other) {
|
| // This should be called with empty info only.
|
| - DCHECK(!other.proxy.get() && !other.watcher_thread.get());
|
| + DCHECK(!other.proxy.get());
|
| }
|
|
|
| ProcessProxyRegistry::ProcessProxyInfo::~ProcessProxyInfo() {
|
| @@ -54,9 +51,18 @@ ProcessProxyRegistry::~ProcessProxyRegistry() {
|
| // on a different thread (it's a LazyInstance).
|
| DetachFromThread();
|
|
|
| + ShutDown();
|
| +}
|
| +
|
| +void ProcessProxyRegistry::ShutDown() {
|
| // Close all proxies we own.
|
| while (!proxy_map_.empty())
|
| CloseProcess(proxy_map_.begin()->first);
|
| +
|
| + if (watcher_thread_) {
|
| + watcher_thread_->Stop();
|
| + watcher_thread_.reset();
|
| + }
|
| }
|
|
|
| // static
|
| @@ -70,13 +76,8 @@ bool ProcessProxyRegistry::OpenProcess(
|
| const ProcessOutputCallbackWithPid& callback) {
|
| DCHECK(CalledOnValidThread());
|
|
|
| - // TODO(tbarzic): Instead of creating a new thread for each new process proxy,
|
| - // use one thread for all processes.
|
| - // We will need new thread for proxy's outpu watcher.
|
| - scoped_ptr<base::Thread> watcher_thread(new base::Thread(kWatcherThreadName));
|
| - if (!watcher_thread->Start()) {
|
| + if (!EnsureWatcherThreadStarted())
|
| return false;
|
| - }
|
|
|
| // Create and open new proxy.
|
| scoped_refptr<ProcessProxy> proxy(new ProcessProxy());
|
| @@ -85,12 +86,12 @@ bool ProcessProxyRegistry::OpenProcess(
|
|
|
| // Kick off watcher.
|
| // We can use Unretained because proxy will stop calling callback after it is
|
| - // closed, which is done befire this object goes away.
|
| - if (!proxy->StartWatchingOnThread(watcher_thread.get(),
|
| - base::Bind(&ProcessProxyRegistry::OnProcessOutput,
|
| - base::Unretained(this), *pid))) {
|
| + // closed, which is done before this object goes away.
|
| + if (!proxy->StartWatchingOutput(
|
| + watcher_thread_->task_runner(),
|
| + base::Bind(&ProcessProxyRegistry::OnProcessOutput,
|
| + base::Unretained(this), *pid))) {
|
| proxy->Close();
|
| - watcher_thread->Stop();
|
| return false;
|
| }
|
|
|
| @@ -100,7 +101,6 @@ bool ProcessProxyRegistry::OpenProcess(
|
| // created because we don't know |pid| then.
|
| ProcessProxyInfo& info = proxy_map_[*pid];
|
| info.proxy.swap(proxy);
|
| - info.watcher_thread.reset(watcher_thread.release());
|
| info.process_id = *pid;
|
| info.callback = callback;
|
| return true;
|
| @@ -123,7 +123,6 @@ bool ProcessProxyRegistry::CloseProcess(pid_t pid) {
|
| return false;
|
|
|
| it->second.proxy->Close();
|
| - it->second.watcher_thread->Stop();
|
| proxy_map_.erase(it);
|
| return true;
|
| }
|
| @@ -156,4 +155,16 @@ void ProcessProxyRegistry::OnProcessOutput(pid_t pid,
|
| CloseProcess(pid);
|
| }
|
|
|
| +bool ProcessProxyRegistry::EnsureWatcherThreadStarted() {
|
| + if (watcher_thread_.get())
|
| + return true;
|
| +
|
| + // TODO(tbarzic): Change process output watcher to watch for fd readability on
|
| + // FILE thread, and move output reading to worker thread instead of
|
| + // spinning a new thread.
|
| + watcher_thread_.reset(new base::Thread(kWatcherThreadName));
|
| + return watcher_thread_->StartWithOptions(
|
| + base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
|
| +}
|
| +
|
| } // namespace chromeos
|
|
|