Index: content/app/content_main_runner.cc |
=================================================================== |
--- content/app/content_main_runner.cc (revision 117304) |
+++ content/app/content_main_runner.cc (working copy) |
@@ -1,8 +1,8 @@ |
-// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#include "content/app/content_main.h" |
+#include "content/public/app/content_main_runner.h" |
#include "base/at_exit.h" |
#include "base/command_line.h" |
@@ -27,6 +27,7 @@ |
#include "content/public/common/sandbox_init.h" |
#include "crypto/nss_util.h" |
#include "ipc/ipc_switches.h" |
+#include "sandbox/src/sandbox_types.h" |
#include "ui/base/ui_base_switches.h" |
#include "ui/base/ui_base_paths.h" |
#include "webkit/glue/webkit_glue.h" |
@@ -75,12 +76,8 @@ |
namespace { |
-#if defined(OS_WIN) |
+#if defined(OS_MACOSX) |
-static CAppModule _Module; |
- |
-#elif defined(OS_MACOSX) |
- |
// Completes the Mach IPC handshake by sending this process' task port to the |
// parent process. The parent is listening on the Mach port given by |
// |GetMachPortName()|. The task port is used by the parent to get CPU/memory |
@@ -141,7 +138,7 @@ |
MSG msg; |
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); |
#endif |
-#if defined(OS_POSIX) && !defined(OS_MACOSX) |
+#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) |
// Various things break when you're using a locale where the decimal |
// separator isn't a period. See e.g. bugs 22782 and 39964. For |
// all processes except the browser process (where we call system |
@@ -260,8 +257,15 @@ |
}; |
for (size_t i = 0; i < arraysize(kMainFunctions); ++i) { |
- if (process_type == kMainFunctions[i].name) |
+ if (process_type == kMainFunctions[i].name) { |
+ if (delegate) { |
+ int exit_code = delegate->RunProcess(process_type, |
+ main_function_params); |
+ if (exit_code >= 0) |
+ return exit_code; |
+ } |
return kMainFunctions[i].function(main_function_params); |
+ } |
} |
#if defined(OS_POSIX) && !defined(OS_MACOSX) |
@@ -279,24 +283,81 @@ |
return 1; |
} |
-} // namespace |
+class ContentMainRunnerImpl : public content::ContentMainRunner { |
+ public: |
+ ContentMainRunnerImpl(); |
jam
2012/01/31 21:11:29
since this class is only in the cc file, there's n
|
+ ~ContentMainRunnerImpl(); |
-namespace content { |
+#if defined(OS_WIN) |
+ virtual int Initialize(HINSTANCE instance, |
+ sandbox::SandboxInterfaceInfo* sandbox_info, |
+ content::ContentMainDelegate* delegate) OVERRIDE; |
+#else |
+ virtual int Initialize(int argc, |
+ const char** argv, |
+ content::ContentMainDelegate* delegate) OVERRIDE; |
+#endif |
+ virtual int Run() OVERRIDE; |
+ virtual void Shutdown() OVERRIDE; |
+ protected: |
+ // True if the runner has been initialized. |
+ bool is_initialized_; |
+ |
+ // True if the runner has been shut down. |
+ bool is_shutdown_; |
+ |
+ // The delegate will outlive this object. |
+ content::ContentMainDelegate* delegate_; |
+ |
+ scoped_ptr<base::AtExitManager> exit_manager_; |
#if defined(OS_WIN) |
-int ContentMain(HINSTANCE instance, |
- sandbox::SandboxInterfaceInfo* sandbox_info, |
- ContentMainDelegate* delegate) { |
+ sandbox::SandboxInterfaceInfo sandbox_info_; |
+ scoped_ptr<CAppModule> app_module_; |
+#elif defined(OS_MACOSX) |
+ scoped_ptr<base::mac::ScopedNSAutoreleasePool> autorelease_pool_; |
+#endif |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ContentMainRunnerImpl); |
+}; |
+ |
+ContentMainRunnerImpl::ContentMainRunnerImpl() |
+ : is_initialized_(false), |
+ is_shutdown_(false) { |
+} |
+ |
+ContentMainRunnerImpl::~ContentMainRunnerImpl() { |
+ if (is_initialized_ && !is_shutdown_) |
+ Shutdown(); |
+} |
+ |
+#if defined(OS_WIN) |
+int ContentMainRunnerImpl::Initialize( |
+ HINSTANCE instance, |
+ sandbox::SandboxInterfaceInfo* sandbox_info, |
+ content::ContentMainDelegate* delegate) { |
+ is_initialized_ = true; |
+ |
// argc/argv are ignored on Windows; see command_line.h for details. |
int argc = 0; |
char** argv = NULL; |
content::RegisterInvalidParamHandler(); |
- _Module.Init(NULL, static_cast<HINSTANCE>(instance)); |
+ app_module_.reset(new CAppModule); |
+ app_module_->Init(NULL, static_cast<HINSTANCE>(instance)); |
+ |
+ if (sandbox_info) |
+ sandbox_info_ = *sandbox_info; |
+ else |
+ memset(&sandbox_info_, 0, sizeof(sandbox_info_)); |
+ |
#else |
-int ContentMain(int argc, |
- const char** argv, |
- ContentMainDelegate* delegate) { |
+int ContentMainRunnerImpl::Initialize( |
+ int argc, |
+ const char** argv, |
+ content::ContentMainDelegate* delegate) { |
+ is_initialized_ = true; |
+ |
// NOTE(willchan): One might ask why this call is done here rather than in |
// process_util_linux.cc with the definition of |
// EnableTerminationOnOutOfMemory(). That's because base shouldn't have a |
@@ -308,9 +369,11 @@ |
tc_set_new_mode(1); |
#endif |
+#if !defined(OS_ANDROID) |
jam
2012/01/31 21:11:29
merge issue?
|
// Set C library locale to make sure CommandLine can parse argument values |
// in correct encoding. |
setlocale(LC_ALL, ""); |
+#endif |
SetupSignalHandlers(); |
@@ -324,18 +387,20 @@ |
#endif // OS_WIN |
+ delegate_ = delegate; |
+ |
base::EnableTerminationOnHeapCorruption(); |
base::EnableTerminationOnOutOfMemory(); |
// The exit manager is in charge of calling the dtors of singleton objects. |
- base::AtExitManager exit_manager; |
+ exit_manager_.reset(new base::AtExitManager); |
#if defined(OS_MACOSX) |
// We need this pool for all the objects created before we get to the |
// event loop, but we don't want to leave them hanging around until the |
// app quits. Each "main" needs to flush this pool right before it goes into |
// its main event loop to get rid of the cruft. |
- base::mac::ScopedNSAutoreleasePool autorelease_pool; |
+ autorelease_pool_.reset(new base::mac::ScopedNSAutoreleasePool()); |
#endif |
CommandLine::Init(argc, argv); |
@@ -445,26 +510,65 @@ |
SetProcessTitleFromCommandLine(argv); |
#endif |
+ // Return -1 to indicate no early termination. |
+ return -1; |
+} |
+ |
+int ContentMainRunnerImpl::Run() { |
+ DCHECK(is_initialized_); |
+ DCHECK(!is_shutdown_); |
+ const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
+ std::string process_type = |
+ command_line.GetSwitchValueASCII(switches::kProcessType); |
+ |
content::MainFunctionParams main_params(command_line); |
#if defined(OS_WIN) |
- main_params.sandbox_info = sandbox_info; |
+ main_params.sandbox_info = &sandbox_info_; |
#elif defined(OS_MACOSX) |
- main_params.autorelease_pool = &autorelease_pool; |
+ main_params.autorelease_pool = autorelease_pool_.get(); |
#endif |
- exit_code = RunNamedProcessTypeMain(process_type, main_params, delegate); |
+ return RunNamedProcessTypeMain(process_type, main_params, delegate_); |
+} |
- if (delegate) delegate->ProcessExiting(process_type); |
+void ContentMainRunnerImpl::Shutdown() { |
+ DCHECK(is_initialized_); |
+ DCHECK(!is_shutdown_); |
+ const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
+ std::string process_type = |
+ command_line.GetSwitchValueASCII(switches::kProcessType); |
+ if (delegate_) delegate_->ProcessExiting(process_type); |
+ |
#if defined(OS_WIN) |
#ifdef _CRTDBG_MAP_ALLOC |
_CrtDumpMemoryLeaks(); |
#endif // _CRTDBG_MAP_ALLOC |
- _Module.Term(); |
+ app_module_->Term(); |
#endif // OS_WIN |
- return exit_code; |
+#if defined(OS_MACOSX) |
+ autorelease_pool_.reset(NULL); |
+#endif |
+ |
+ exit_manager_.reset(NULL); |
+ |
+#if defined(OS_WIN) |
+ app_module_.reset(NULL); |
+#endif |
+ |
+ delegate_ = NULL; |
+ is_shutdown_ = true; |
} |
+} // namespace |
+ |
+namespace content { |
+ |
+// static |
+ContentMainRunner* ContentMainRunner::Create() { |
+ return new ContentMainRunnerImpl(); |
+} |
+ |
} // namespace content |