summaryrefslogtreecommitdiffstats
path: root/chrome/common/child_process.cc
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-20 07:15:17 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-20 07:15:17 +0000
commitea51de3307a6a5947ca047fa9d0e20359fdcf658 (patch)
treec1a49c1d41c4bfbf74ddbc28c371f840dd2848fa /chrome/common/child_process.cc
parentb6aedfff89cd93f07c1c38a13062801e81bf26e4 (diff)
downloadchromium_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.cc108
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;
+}
+