diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-20 07:15:17 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-20 07:15:17 +0000 |
commit | ea51de3307a6a5947ca047fa9d0e20359fdcf658 (patch) | |
tree | c1a49c1d41c4bfbf74ddbc28c371f840dd2848fa /chrome/common/child_process.cc | |
parent | b6aedfff89cd93f07c1c38a13062801e81bf26e4 (diff) | |
download | chromium_src-ea51de3307a6a5947ca047fa9d0e20359fdcf658.zip chromium_src-ea51de3307a6a5947ca047fa9d0e20359fdcf658.tar.gz chromium_src-ea51de3307a6a5947ca047fa9d0e20359fdcf658.tar.bz2 |
Reverting 10080.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10082 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/common/child_process.cc')
-rw-r--r-- | chrome/common/child_process.cc | 108 |
1 files changed, 77 insertions, 31 deletions
diff --git a/chrome/common/child_process.cc b/chrome/common/child_process.cc index 27265d3..b64984c 100644 --- a/chrome/common/child_process.cc +++ b/chrome/common/child_process.cc @@ -4,63 +4,109 @@ #include "chrome/common/child_process.h" +#include "base/atomic_ref_count.h" #include "base/basictypes.h" +#include "base/command_line.h" #include "base/string_util.h" -#include "chrome/common/child_thread.h" +#include "base/waitable_event.h" +#include "chrome/common/chrome_switches.h" +#include "webkit/glue/webkit_glue.h" ChildProcess* ChildProcess::child_process_; +MessageLoop* ChildProcess::main_thread_loop_; +static base::AtomicRefCount ref_count; +base::WaitableEvent* ChildProcess::shutdown_event_; -ChildProcess::ChildProcess(ChildThread* child_thread) - : shutdown_event_(true, false), - ref_count_(0), - child_thread_(child_thread) { + +ChildProcess::ChildProcess() { DCHECK(!child_process_); - child_process_ = this; - if (child_thread_.get()) // null in unittests. - child_thread_->Run(); } ChildProcess::~ChildProcess() { DCHECK(child_process_ == this); - - // Signal this event before destroying the child process. That way all - // background threads can cleanup. - // For example, in the renderer the RenderThread instances will be able to - // notice shutdown before the render process begins waiting for them to exit. - shutdown_event_.Signal(); - - if (child_thread_.get()) - child_thread_->Stop(); - - child_process_ = NULL; } // Called on any thread void ChildProcess::AddRefProcess() { - base::AtomicRefCountInc(&ref_count_); + base::AtomicRefCountInc(&ref_count); } // Called on any thread void ChildProcess::ReleaseProcess() { - DCHECK(!base::AtomicRefCountIsZero(&ref_count_)); + DCHECK(!base::AtomicRefCountIsZero(&ref_count)); DCHECK(child_process_); - if (!base::AtomicRefCountDec(&ref_count_)) + if (!base::AtomicRefCountDec(&ref_count)) child_process_->OnFinalRelease(); } -base::WaitableEvent* ChildProcess::GetShutDownEvent() { - DCHECK(child_process_); - return &child_process_->shutdown_event_; -} - // Called on any thread +// static bool ChildProcess::ProcessRefCountIsZero() { - return base::AtomicRefCountIsZero(&ref_count_); + return base::AtomicRefCountIsZero(&ref_count); } void ChildProcess::OnFinalRelease() { - if (child_thread_.get()) { - child_thread_->owner_loop()->PostTask( - FROM_HERE, new MessageLoop::QuitTask()); + DCHECK(main_thread_loop_); + main_thread_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask()); +} + +base::WaitableEvent* ChildProcess::GetShutDownEvent() { + return shutdown_event_; +} + +// On error, it is OK to leave the global pointers, as long as the only +// non-NULL pointers are valid. GlobalCleanup will always get called, which +// will delete any non-NULL services. +bool ChildProcess::GlobalInit(const std::wstring &channel_name, + ChildProcessFactoryInterface *factory) { + // OK to be called multiple times. + if (main_thread_loop_) + return true; + + if (channel_name.empty()) { + NOTREACHED() << "Unable to get the channel name"; + return false; } + + // Remember the current message loop, so we can communicate with this thread + // again when we need to shutdown (see ReleaseProcess). + main_thread_loop_ = MessageLoop::current(); + + // An event that will be signalled when we shutdown. + shutdown_event_ = new base::WaitableEvent(true, false); + + child_process_ = factory->Create(channel_name); + + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + if (command_line.HasSwitch(switches::kUserAgent)) { +#if defined(OS_WIN) + // TODO(port): calling this connects an, otherwise disconnected, subgraph + // of symbols, causing huge numbers of linker errors. + webkit_glue::SetUserAgent(WideToUTF8( + command_line.GetSwitchValue(switches::kUserAgent))); +#endif + } + + return true; } + +void ChildProcess::GlobalCleanup() { + // Signal this event before destroying the child process. That way all + // background threads. + // For example, in the renderer the RenderThread instances will be able to + // notice shutdown before the render process begins waiting for them to exit. + shutdown_event_->Signal(); + + // Destroy the child process first to force all background threads to + // terminate before we bring down other resources. (We null pointers + // just in case.) + child_process_->Cleanup(); + delete child_process_; + child_process_ = NULL; + + main_thread_loop_ = NULL; + + delete shutdown_event_; + shutdown_event_ = NULL; +} + |