content_main_runner.cc revision a02191e04bc25c4935f804f2c080ae28663d096d
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/app/content_main_runner.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/allocator/allocator_extension.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/at_exit.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/debugger.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/icu_util.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/stats_table.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
2158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "base/process/launch.h"
2258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "base/process/memory.h"
2358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "base/process/process_handle.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/profiler/alternate_timer.h"
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/browser_main.h"
293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/browser/gpu/gpu_process_host.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/set_process_title.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/url_schemes.h"
3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/gpu/in_process_gpu_thread.h"
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/app/content_main.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/app/content_main_delegate.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/app/startup_helper_win.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/content_browser_client.h"
373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/public/browser/utility_process_host.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_client.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_constants.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_paths.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_switches.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/main_function_params.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/sandbox_init.h"
4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/renderer/in_process_renderer_thread.h"
4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/utility/in_process_utility_thread.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/nss_util.h"
48c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ipc/ipc_descriptors.h"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_switches.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/media.h"
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox_types.h"
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/ui_base_paths.h"
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/ui_base_switches.h"
54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/win/dpi.h"
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_TCMALLOC)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/tcmalloc/chromium/src/gperftools/malloc_extension.h"
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TYPE_PROFILING)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/allocator/type_profiler.h"
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/allocator/type_profiler_tcmalloc.h"
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_IOS)
65c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/app/mojo/mojo_init.h"
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/plugin/content_plugin_client.h"
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/content_renderer_client.h"
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/utility/content_utility_client.h"
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <atlbase.h>
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <atlapp.h>
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <malloc.h>
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <cstring>
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/mac/scoped_nsautorelease_pool.h"
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_IOS)
79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/power_monitor/power_monitor_device_source.h"
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/mach_broker_mac.h"
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/sandbox_init_mac.h"
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // !OS_IOS
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // OS_WIN
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <signal.h>
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/posix/global_descriptors.h"
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_descriptors.h"
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/zygote_fork_delegate_linux.h"
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/zygote/zygote_main.h"
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // OS_POSIX
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX) && defined(USE_TCMALLOC)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C" {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int tc_set_new_mode(int mode);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int GpuMain(const content::MainFunctionParams&);
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ENABLE_PLUGINS)
109a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if !defined(OS_LINUX)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int PluginMain(const content::MainFunctionParams&);
111a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#endif
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int PpapiPluginMain(const MainFunctionParams&);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int PpapiBrokerMain(const MainFunctionParams&);
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int RendererMain(const content::MainFunctionParams&);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int UtilityMain(const MainFunctionParams&);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int WorkerMain(const MainFunctionParams&);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In order to have Theme support, we need to connect to the theme service.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This needs to be done before we lock down the process. Officially this
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// can be done with OpenThemeData() but it fails unless you pass a valid
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// window at least the first time. Interestingly, the very act of creating a
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// window also sets the connection to the theme service.
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EnableThemeSupportOnAllWindowStations() {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HDESK desktop_handle = ::OpenInputDesktop(0, FALSE, READ_CONTROL);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (desktop_handle) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This means we are running in an input desktop, which implies WinSta0.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::CloseDesktop(desktop_handle);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HWINSTA current_station = ::GetProcessWindowStation();
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(current_station);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HWINSTA winsta0 = ::OpenWindowStationA("WinSta0", FALSE, GENERIC_READ);
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!winsta0) {
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DVLOG(0) << "Unable to open to WinSta0, we: "<< ::GetLastError();
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!::SetProcessWindowStation(winsta0)) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Could not set the alternate window station. There is a possibility
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // that the theme wont be correctly initialized.
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "Unable to switch to WinSta0, we: "<< ::GetLastError();
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ::CloseWindowStation(winsta0);
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HWND window = ::CreateWindowExW(0, L"Static", L"", WS_POPUP | WS_DISABLED,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  CW_USEDEFAULT, 0, 0, 0,  HWND_MESSAGE, NULL,
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  ::GetModuleHandleA(NULL), NULL);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!window) {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(WARNING) << "failed to enable theme support";
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::DestroyWindow(window);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window = NULL;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Revert the window station.
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!::SetProcessWindowStation(current_station)) {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We failed to switch back to the secure window station. This might
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // confuse the process enough that we should kill it now.
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(FATAL) << "Failed to restore alternate window station";
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!::CloseWindowStation(winsta0)) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We might be leaking a winsta0 handle.  This is a security risk, but
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // since we allow fail over to no desktop protection in low memory
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // condition, this is not a big risk.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_WIN)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::LazyInstance<ContentBrowserClient>
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_empty_content_browser_client = LAZY_INSTANCE_INITIALIZER;
1822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#if !defined(OS_IOS) && !defined(CHROME_MULTIPLE_DLL_BROWSER)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::LazyInstance<ContentPluginClient>
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_empty_content_plugin_client = LAZY_INSTANCE_INITIALIZER;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::LazyInstance<ContentRendererClient>
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_empty_content_renderer_client = LAZY_INSTANCE_INITIALIZER;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::LazyInstance<ContentUtilityClient>
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_empty_content_utility_client = LAZY_INSTANCE_INITIALIZER;
1892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#endif  // !OS_IOS && !CHROME_MULTIPLE_DLL_BROWSER
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static CAppModule _Module;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_WIN)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && !defined(OS_IOS)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Setup signal-handling state: resanitize most signals, ignore SIGPIPE.
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetupSignalHandlers() {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sanitise our signal handling state. Signals that were ignored by our
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // parent will also be ignored by us. We also inherit our parent's sigmask.
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sigset_t empty_signal_set;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(0 == sigemptyset(&empty_signal_set));
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(0 == sigprocmask(SIG_SETMASK, &empty_signal_set, NULL));
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct sigaction sigact;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(&sigact, 0, sizeof(sigact));
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sigact.sa_handler = SIG_DFL;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int signals_to_reset[] =
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      {SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, SIGFPE, SIGSEGV,
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       SIGALRM, SIGTERM, SIGCHLD, SIGBUS, SIGTRAP};  // SIGPIPE is set below.
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (unsigned i = 0; i < arraysize(signals_to_reset); i++) {
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(0 == sigaction(signals_to_reset[i], &sigact, NULL));
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Always ignore SIGPIPE.  We check the return value of write().
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(signal(SIGPIPE, SIG_IGN) != SIG_ERR);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // OS_POSIX && !OS_IOS
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommonSubprocessInit(const std::string& process_type) {
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HACK: Let Windows know that we have started.  This is needed to suppress
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the IDC_APPSTARTING cursor from being displayed for a prolonged period
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // while a subprocess is starting.
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PostThreadMessage(GetCurrentThreadId(), WM_NULL, 0, 0);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MSG msg;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Various things break when you're using a locale where the decimal
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // separator isn't a period.  See e.g. bugs 22782 and 39964.  For
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // all processes except the browser process (where we call system
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // APIs that may rely on the correct locale for formatting numbers
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when presenting them to the user), reset the locale for numeric
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // formatting.
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that this is not correct for plugin processes -- they can
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // surface UI -- but it's likely they get this wrong too so why not.
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  setlocale(LC_NUMERIC, "C");
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Only needed on Windows for creating stats tables.
246c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if defined(OS_WIN)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static base::ProcessId GetBrowserPid(const CommandLine& command_line) {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ProcessId browser_pid = base::GetCurrentProcId();
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (command_line.HasSwitch(switches::kProcessChannelID)) {
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string channel_name =
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        command_line.GetSwitchValueASCII(switches::kProcessChannelID);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int browser_pid_int;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::StringToInt(channel_name, &browser_pid_int);
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    browser_pid = static_cast<base::ProcessId>(browser_pid_int);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_NE(browser_pid_int, 0);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return browser_pid;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
260c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void InitializeStatsTable(const CommandLine& command_line) {
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initialize the Stats Counters table.  With this initialized,
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the StatsViewer can be utilized to read counters outside of
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Chrome.  These lines can be commented out to effectively turn
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // counters 'off'.  The table is created and exists for the life
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of the process.  It is not cleaned up.
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (command_line.HasSwitch(switches::kEnableStatsTable)) {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // NOTIMPLEMENTED: we probably need to shut this down correctly to avoid
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // leaking shared memory regions on posix platforms.
271c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if defined(OS_POSIX)
272c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // Stats table is in the global file descriptors table on Posix.
273c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    base::GlobalDescriptors* global_descriptors =
274c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        base::GlobalDescriptors::GetInstance();
275c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    base::FileDescriptor table_ident;
276c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (global_descriptors->MaybeGet(kStatsTableSharedMemFd) != -1) {
277c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      // Open the shared memory file descriptor passed by the browser process.
278c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      table_ident = base::FileDescriptor(
279c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          global_descriptors->Get(kStatsTableSharedMemFd), false);
280c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    }
281c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#elif defined(OS_WIN)
282c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // Stats table is in a named segment on Windows. Use the PID to make this
283c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // unique on the system.
284c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    std::string table_ident =
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::StringPrintf("%s-%u", kStatsFilename,
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          static_cast<unsigned int>(GetBrowserPid(command_line)));
287c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif
288c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    base::StatsTable* stats_table =
289c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        new base::StatsTable(table_ident, kStatsMaxThreads, kStatsMaxCounters);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::StatsTable::set_current(stats_table);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ContentClientInitializer {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Set(const std::string& process_type,
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  ContentMainDelegate* delegate) {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ContentClient* content_client = GetContentClient();
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (process_type.empty()) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (delegate)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content_client->browser_ = delegate->CreateContentBrowserClient();
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!content_client->browser_)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content_client->browser_ = &g_empty_content_browser_client.Get();
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#if !defined(OS_IOS) && !defined(CHROME_MULTIPLE_DLL_BROWSER)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (process_type == switches::kPluginProcess ||
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        process_type == switches::kPpapiPluginProcess) {
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (delegate)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content_client->plugin_ = delegate->CreateContentPluginClient();
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!content_client->plugin_)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content_client->plugin_ = &g_empty_content_plugin_client.Get();
313b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      // Single process not supported in split dll mode.
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (process_type == switches::kRendererProcess ||
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               CommandLine::ForCurrentProcess()->HasSwitch(
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   switches::kSingleProcess)) {
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (delegate)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content_client->renderer_ = delegate->CreateContentRendererClient();
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!content_client->renderer_)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content_client->renderer_ = &g_empty_content_renderer_client.Get();
3217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
3227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (process_type == switches::kUtilityProcess ||
3247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        CommandLine::ForCurrentProcess()->HasSwitch(
3257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            switches::kSingleProcess)) {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (delegate)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content_client->utility_ = delegate->CreateContentUtilityClient();
328b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      // TODO(scottmg): http://crbug.com/237249 Should be in _child.
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!content_client->utility_)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content_client->utility_ = &g_empty_content_utility_client.Get();
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#endif  // !OS_IOS && !CHROME_MULTIPLE_DLL_BROWSER
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We dispatch to a process-type-specific FooMain() based on a command-line
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// flag.  This struct is used to build a table of (flag, main function) pairs.
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MainFunction {
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* name;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int (*function)(const MainFunctionParams&);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// On platforms that use the zygote, we have a special subset of
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// subprocesses that are launched via the zygote.  This function
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// fills in some process-launching bits around ZygoteMain().
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the exit code of the subprocess.
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int RunZygote(const MainFunctionParams& main_function_params,
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              ContentMainDelegate* delegate) {
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const MainFunction kMainFunctions[] = {
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { switches::kRendererProcess,    RendererMain },
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { switches::kWorkerProcess,      WorkerMain },
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ENABLE_PLUGINS)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { switches::kPpapiPluginProcess, PpapiPluginMain },
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { switches::kUtilityProcess,     UtilityMain },
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ZygoteForkDelegate> zygote_fork_delegate;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate) {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    zygote_fork_delegate.reset(delegate->ZygoteStarting());
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Each Renderer we spawn will re-attempt initialization of the media
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // libraries, at which point failure will be detected and handled, so
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // we do not need to cope with initialization failures here.
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath media_path;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (PathService::Get(DIR_MEDIA_LIBS, &media_path))
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      media::InitializeMediaLibrary(media_path);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This function call can return multiple times, once per fork().
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ZygoteMain(main_function_params, zygote_fork_delegate.get()))
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 1;
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate) delegate->ZygoteForked();
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Zygote::HandleForkRequest may have reallocated the command
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // line so update it here with the new version.
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string process_type =
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      command_line.GetSwitchValueASCII(switches::kProcessType);
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ContentClientInitializer::Set(process_type, delegate);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The StatsTable must be initialized in each process; we already
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // initialized for the browser process, now we need to initialize
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // within the new processes as well.
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeStatsTable(command_line);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MainFunctionParams main_params(command_line);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kMainFunctions); ++i) {
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (process_type == kMainFunctions[i].name)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kMainFunctions[i].function(main_params);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return delegate->RunProcess(process_type, main_params);
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED() << "Unknown zygote process type: " << process_type;
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 1;
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_IOS)
404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static void RegisterMainThreadFactories() {
405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if !defined(CHROME_MULTIPLE_DLL_BROWSER)
406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  UtilityProcessHost::RegisterUtilityMainThreadFactory(
407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      CreateInProcessUtilityThread);
408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RenderProcessHost::RegisterRendererMainThreadFactory(
409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      CreateInProcessRendererThread);
410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GpuProcessHost::RegisterGpuMainThreadFactory(
411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      CreateInProcessGpuThread);
412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#else
413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CommandLine& command_line = *CommandLine::ForCurrentProcess();
414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (command_line.HasSwitch(switches::kSingleProcess)) {
415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    LOG(FATAL) <<
416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "--single-process is not supported in chrome multiple dll browser.";
417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (command_line.HasSwitch(switches::kInProcessGPU)) {
419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    LOG(FATAL) <<
420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "--in-process-gpu is not supported in chrome multiple dll browser.";
421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Run the FooMain() for a given process type.
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If |process_type| is empty, runs BrowserMain().
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the exit code for this process.
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int RunNamedProcessTypeMain(
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& process_type,
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MainFunctionParams& main_function_params,
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ContentMainDelegate* delegate) {
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const MainFunction kMainFunctions[] = {
4332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#if !defined(CHROME_MULTIPLE_DLL_CHILD)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "",                            BrowserMain },
435ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#endif
4362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#if !defined(CHROME_MULTIPLE_DLL_BROWSER)
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ENABLE_PLUGINS)
438a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if !defined(OS_LINUX)
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { switches::kPluginProcess,      PluginMain },
440a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#endif
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { switches::kWorkerProcess,      WorkerMain },
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { switches::kPpapiPluginProcess, PpapiPluginMain },
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { switches::kPpapiBrokerProcess, PpapiBrokerMain },
444ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#endif  // ENABLE_PLUGINS
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { switches::kUtilityProcess,     UtilityMain },
446b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    { switches::kRendererProcess,    RendererMain },
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { switches::kGpuProcess,         GpuMain },
4482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#endif  // !CHROME_MULTIPLE_DLL_BROWSER
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RegisterMainThreadFactories();
4523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kMainFunctions); ++i) {
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (process_type == kMainFunctions[i].name) {
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (delegate) {
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int exit_code = delegate->RunProcess(process_type,
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            main_function_params);
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID)
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // In Android's browser process, the negative exit code doesn't mean the
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // default behavior should be used as the UI message loop is managed by
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // the Java and the browser process's default behavior is always
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // overridden.
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (process_type.empty())
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return exit_code;
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (exit_code >= 0)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return exit_code;
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kMainFunctions[i].function(main_function_params);
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Zygote startup is special -- see RunZygote comments above
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for why we don't use ZygoteMain directly.
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (process_type == switches::kZygoteProcess)
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return RunZygote(main_function_params, delegate);
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If it's a process we don't know about, the embedder should know.
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate)
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return delegate->RunProcess(process_type, main_function_params);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED() << "Unknown process type: " << process_type;
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 1;
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // !OS_IOS
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ContentMainRunnerImpl : public ContentMainRunner {
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ContentMainRunnerImpl()
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : is_initialized_(false),
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        is_shutdown_(false),
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        completed_basic_startup_(false),
49523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        delegate_(NULL),
49623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        ui_task_(NULL) {
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(&sandbox_info_, 0, sizeof(sandbox_info_));
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~ContentMainRunnerImpl() {
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (is_initialized_ && !is_shutdown_)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Shutdown();
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_TCMALLOC)
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static bool GetAllocatorWasteSizeThunk(size_t* size) {
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t heap_size, allocated_bytes, unmapped_bytes;
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MallocExtension* ext = MallocExtension::instance();
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (ext->GetNumericProperty("generic.heap_size", &heap_size) &&
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ext->GetNumericProperty("generic.current_allocated_bytes",
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                &allocated_bytes) &&
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ext->GetNumericProperty("tcmalloc.pageheap_unmapped_bytes",
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                &unmapped_bytes)) {
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *size = heap_size - allocated_bytes - unmapped_bytes;
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(false);
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void GetStatsThunk(char* buffer, int buffer_length) {
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MallocExtension::instance()->GetStats(buffer, buffer_length);
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void ReleaseFreeMemoryThunk() {
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MallocExtension::instance()->ReleaseFreeMemory();
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
532a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual int Initialize(const ContentMainParams& params) OVERRIDE {
53323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ui_task_ = params.ui_task;
53423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
535effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#if defined(OS_WIN)
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RegisterInvalidParamHandler();
537a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    _Module.Init(NULL, static_cast<HINSTANCE>(params.instance));
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
539a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    sandbox_info_ = *params.sandbox_info;
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else  // !OS_WIN
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_ANDROID)
543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // See note at the initialization of ExitManager, below; basically,
544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // only Android builds have the ctor/dtor handlers set up to use
545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // TRACE_EVENT right away.
546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TRACE_EVENT0("startup", "ContentMainRunnerImpl::Initialize");
547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif  // OS_ANDROID
548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // NOTE(willchan): One might ask why these TCMalloc-related calls are done
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // here rather than in process_util_linux.cc with the definition of
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // EnableTerminationOnOutOfMemory().  That's because base shouldn't have a
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // dependency on TCMalloc.  Really, we ought to have our allocator shim code
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // implement this EnableTerminationOnOutOfMemory() function.  Whateverz.
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This works for now.
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX) && defined(USE_TCMALLOC)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TYPE_PROFILING)
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::type_profiler::InterceptFunctions::SetFunctions(
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::type_profiler::NewInterceptForTCMalloc,
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::type_profiler::DeleteInterceptForTCMalloc);
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // For tcmalloc, we need to tell it to behave like new.
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tc_set_new_mode(1);
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // On windows, we've already set these thunks up in _heap_init()
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::allocator::SetGetAllocatorWasteSizeFunction(
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        GetAllocatorWasteSizeThunk);
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::allocator::SetGetStatsFunction(GetStatsThunk);
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::allocator::SetReleaseFreeMemoryFunction(ReleaseFreeMemoryThunk);
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Provide optional hook for monitoring allocation quantities on a
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // per-thread basis.  Only set the hook if the environment indicates this
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // needs to be enabled.
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* profiling = getenv(tracked_objects::kAlternateProfilerTime);
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (profiling &&
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (atoi(profiling) == tracked_objects::TIME_SOURCE_TYPE_TCMALLOC)) {
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tracked_objects::SetAlternateTimeSource(
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          MallocExtension::GetBytesAllocatedOnCurrentThread,
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          tracked_objects::TIME_SOURCE_TYPE_TCMALLOC);
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif  // !OS_MACOSX && USE_TCMALLOC
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // On Android,
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // - setlocale() is not supported.
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // - We do not override the signal handlers so that we can get
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   stack trace when crashing.
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // - The ipc_fd is passed through the Java service.
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Thus, these are all disabled.
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_ANDROID) && !defined(OS_IOS)
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Set C library locale to make sure CommandLine can parse argument values
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // in correct encoding.
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    setlocale(LC_ALL, "");
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetupSignalHandlers();
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::GlobalDescriptors* g_fds = base::GlobalDescriptors::GetInstance();
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_fds->Set(kPrimaryIPCChannel,
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               kPrimaryIPCChannel + base::GlobalDescriptors::kBaseDescriptor);
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // !OS_ANDROID && !OS_IOS
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_LINUX) || defined(OS_OPENBSD)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_fds->Set(kCrashDumpSignal,
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               kCrashDumpSignal + base::GlobalDescriptors::kBaseDescriptor);
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // !OS_WIN
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    is_initialized_ = true;
610a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    delegate_ = params.delegate;
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::EnableTerminationOnHeapCorruption();
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::EnableTerminationOnOutOfMemory();
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The exit manager is in charge of calling the dtors of singleton objects.
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // On Android, AtExitManager is set up when library is loaded.
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // On iOS, it's set up in main(), which can't call directly through to here.
618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // A consequence of this is that you can't use the ctor/dtor-based
619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // TRACE_EVENT methods on Linux or iOS builds till after we set this up.
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_ANDROID) && !defined(OS_IOS)
62123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    if (!ui_task_) {
62223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      // When running browser tests, don't create a second AtExitManager as that
62323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      // interfers with shutdown when objects created before ContentMain is
62423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      // called are destructed when it returns.
62523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      exit_manager_.reset(new base::AtExitManager);
62623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    }
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // !OS_ANDROID && !OS_IOS
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We need this pool for all the objects created before we get to the
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // event loop, but we don't want to leave them hanging around until the
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // app quits. Each "main" needs to flush this pool right before it goes into
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // its main event loop to get rid of the cruft.
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    autorelease_pool_.reset(new base::mac::ScopedNSAutoreleasePool());
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // On Android, the command line is initialized when library is loaded and
638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // we have already started our TRACE_EVENT0.
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_ANDROID)
640a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // argc/argv are ignored on Windows and Android; see command_line.h for
641a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // details.
642a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int argc = 0;
643a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const char** argv = NULL;
644a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
645a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if !defined(OS_WIN)
646a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    argc = params.argc;
647a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    argv = params.argv;
648a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
649a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandLine::Init(argc, argv);
651a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
652a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if !defined(OS_IOS)
653a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    SetProcessTitleFromCommandLine(argv);
654a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif // !OS_ANDROID
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int exit_code;
658a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (delegate_ && delegate_->BasicStartupComplete(&exit_code))
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return exit_code;
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    completed_basic_startup_ = true;
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CommandLine& command_line = *CommandLine::ForCurrentProcess();
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string process_type =
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        command_line.GetSwitchValueASCII(switches::kProcessType);
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
667c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if !defined(OS_IOS)
668effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // Initialize mojo here so that services can be registered.
669effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    InitializeMojo();
670effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#endif
671effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!GetContentClient())
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetContentClient(&empty_content_client_);
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ContentClientInitializer::Set(process_type, delegate_);
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Route stdio to parent console (if any) or create one.
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (command_line.HasSwitch(switches::kEnableLogging))
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::RouteStdioToConsole();
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Enable startup tracing asap to avoid early TRACE_EVENT calls being
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ignored.
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (command_line.HasSwitch(switches::kTraceStartup)) {
685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::debug::CategoryFilter category_filter(
686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          command_line.GetSwitchValueASCII(switches::kTraceStartup));
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::debug::TraceLog::GetInstance()->SetEnabled(
688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          category_filter,
6895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::debug::TraceLog::RECORDING_MODE,
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::debug::TraceLog::RECORD_UNTIL_FULL);
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if !defined(OS_ANDROID)
693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Android tracing started at the beginning of the method.
694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Other OSes have to wait till we get here in order for all the memory
695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // management setup to be completed.
696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TRACE_EVENT0("startup", "ContentMainRunnerImpl::Initialize");
697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif // !OS_ANDROID
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) && !defined(OS_IOS)
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We need to allocate the IO Ports before the Sandbox is initialized or
701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // the first instance of PowerMonitor is created.
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // It's important not to allocate the ports for processes which don't
703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // register with the power monitor - see crbug.com/88867.
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (process_type.empty() ||
705a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        (delegate_ &&
706a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         delegate_->ProcessRegistersWithSystemProcess(process_type))) {
707a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      base::PowerMonitorDeviceSource::AllocateSystemIOPorts();
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!process_type.empty() &&
711a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        (!delegate_ || delegate_->ShouldSendMachPort(process_type))) {
712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      MachBroker::ChildSendTaskPortToParent();
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN)
71558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (command_line.HasSwitch(switches::kEnableHighResolutionTime))
71658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::TimeTicks::SetNowIsHighResNowIfSupported();
71758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This must be done early enough since some helper functions like
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // IsTouchEnabled, needed to load resources, may call into the theme dll.
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EnableThemeSupportOnAllWindowStations();
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetupCRT(command_line);
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX)
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!process_type.empty()) {
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // When you hit Ctrl-C in a terminal running the browser
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // process, a SIGINT is delivered to the entire process group.
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // When debugging the browser process via gdb, gdb catches the
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // SIGINT for the browser process (and dumps you back to the gdb
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // console) but doesn't for the child processes, killing them.
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The fix is to have child processes ignore SIGINT; they'll die
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // on their own when the browser process goes away.
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      //
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Note that we *can't* rely on BeingDebugged to catch this case because
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // we are the child process, which is not being debugged.
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // TODO(evanm): move this to some shared subprocess-init function.
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!base::debug::BeingDebugged())
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        signal(SIGINT, SIG_IGN);
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_NSS)
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    crypto::EarlySetupForNSSInit();
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::RegisterPathProvider();
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RegisterPathProvider();
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RegisterContentSchemes(true);
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    CHECK(base::i18n::InitializeICU());
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InitializeStatsTable(command_line);
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
754a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (delegate_)
755a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      delegate_->PreSandboxStartup();
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!process_type.empty())
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CommonSubprocessInit(process_type);
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
761a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CHECK(InitializeSandbox(params.sandbox_info));
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX) && !defined(OS_IOS)
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (process_type == switches::kRendererProcess ||
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        process_type == switches::kPpapiPluginProcess ||
765a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        (delegate_ && delegate_->DelaySandboxInitialization(process_type))) {
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // On OS X the renderer sandbox needs to be initialized later in the
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // startup sequence in RendererMainPlatformDelegate::EnableSandbox().
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CHECK(InitializeSandbox());
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
773a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (delegate_)
774a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      delegate_->SandboxInitialized(process_type);
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Return -1 to indicate no early termination.
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1;
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int Run() OVERRIDE {
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(is_initialized_);
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!is_shutdown_);
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CommandLine& command_line = *CommandLine::ForCurrentProcess();
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string process_type =
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          command_line.GetSwitchValueASCII(switches::kProcessType);
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MainFunctionParams main_params(command_line);
78823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    main_params.ui_task = ui_task_;
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    main_params.sandbox_info = &sandbox_info_;
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX)
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    main_params.autorelease_pool = autorelease_pool_.get();
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_IOS)
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return RunNamedProcessTypeMain(process_type, main_params, delegate_);
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 1;
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Shutdown() OVERRIDE {
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(is_initialized_);
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!is_shutdown_);
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (completed_basic_startup_ && delegate_) {
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const CommandLine& command_line = *CommandLine::ForCurrentProcess();
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string process_type =
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          command_line.GetSwitchValueASCII(switches::kProcessType);
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_->ProcessExiting(process_type);
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
814c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if !defined(OS_IOS)
815e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    ShutdownMojo();
816e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#endif
817e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _CRTDBG_MAP_ALLOC
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    _CrtDumpMemoryLeaks();
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // _CRTDBG_MAP_ALLOC
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    _Module.Term();
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // OS_WIN
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX)
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    autorelease_pool_.reset(NULL);
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exit_manager_.reset(NULL);
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_ = NULL;
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    is_shutdown_ = true;
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // True if the runner has been initialized.
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_initialized_;
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // True if the runner has been shut down.
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_shutdown_;
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // True if basic startup was completed.
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool completed_basic_startup_;
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used if the embedder doesn't set one.
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ContentClient empty_content_client_;
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The delegate will outlive this object.
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ContentMainDelegate* delegate_;
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::AtExitManager> exit_manager_;
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sandbox::SandboxInterfaceInfo sandbox_info_;
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX)
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::mac::ScopedNSAutoreleasePool> autorelease_pool_;
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  base::Closure* ui_task_;
86023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ContentMainRunnerImpl);
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ContentMainRunner* ContentMainRunner::Create() {
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new ContentMainRunnerImpl();
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
870