michael@0: // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: #include "chrome/common/child_process.h" michael@0: michael@0: #include "base/basictypes.h" michael@0: #include "base/string_util.h" michael@0: #include "chrome/common/child_thread.h" michael@0: michael@0: ChildProcess* ChildProcess::child_process_; michael@0: michael@0: ChildProcess::ChildProcess(ChildThread* child_thread) michael@0: : child_thread_(child_thread), michael@0: ref_count_(0), michael@0: shutdown_event_(true, false) { michael@0: DCHECK(!child_process_); michael@0: child_process_ = this; michael@0: if (child_thread_.get()) // null in unittests. michael@0: child_thread_->Run(); michael@0: } michael@0: michael@0: ChildProcess::~ChildProcess() { michael@0: DCHECK(child_process_ == this); michael@0: michael@0: // Signal this event before destroying the child process. That way all michael@0: // background threads can cleanup. michael@0: // For example, in the renderer the RenderThread instances will be able to michael@0: // notice shutdown before the render process begins waiting for them to exit. michael@0: shutdown_event_.Signal(); michael@0: michael@0: if (child_thread_.get()) michael@0: child_thread_->Stop(); michael@0: michael@0: child_process_ = NULL; michael@0: } michael@0: michael@0: void ChildProcess::AddRefProcess() { michael@0: DCHECK(!child_thread_.get() || // null in unittests. michael@0: MessageLoop::current() == child_thread_->message_loop()); michael@0: ref_count_++; michael@0: } michael@0: michael@0: void ChildProcess::ReleaseProcess() { michael@0: DCHECK(!child_thread_.get() || // null in unittests. michael@0: MessageLoop::current() == child_thread_->message_loop()); michael@0: DCHECK(ref_count_); michael@0: DCHECK(child_process_); michael@0: if (--ref_count_) michael@0: return; michael@0: michael@0: if (child_thread_.get()) // null in unittests. michael@0: child_thread_->OnProcessFinalRelease(); michael@0: } michael@0: michael@0: base::WaitableEvent* ChildProcess::GetShutDownEvent() { michael@0: DCHECK(child_process_); michael@0: return &child_process_->shutdown_event_; michael@0: }