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)
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/child/child_thread.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <signal.h>
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
91e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include <string>
101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/allocator/allocator_extension.h"
127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/base_switches.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/basictypes.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/debug/leak_annotations.h"
16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/lazy_instance.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/logging.h"
189ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
1946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/message_loop/timer_slack.h"
2058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "base/process/kill.h"
2158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "base/process/process_handle.h"
226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/synchronization/condition_variable.h"
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/synchronization/lock.h"
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/threading/thread_local.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/tracked_objects.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/tracing/child_trace_message_filter.h"
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/child/child_histogram_message_filter.h"
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/child/child_process.h"
31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/child/child_resource_message_filter.h"
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/child/child_shared_bitmap_manager.h"
33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/child/fileapi/file_system_dispatcher.h"
340de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "content/child/fileapi/webfilesystem_impl.h"
355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/child/mojo/mojo_application.h"
36a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "content/child/power_monitor_broadcast_source.h"
37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/child/quota_dispatcher.h"
38558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/child/quota_message_filter.h"
39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/child/resource_dispatcher.h"
401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/child/service_worker/service_worker_message_filter.h"
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/child/socket_stream_dispatcher.h"
42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/child/thread_safe_sender.h"
4368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "content/child/websocket_dispatcher.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/child_process_messages.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_switches.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_logging.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_switches.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_sync_channel.h"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_sync_message_filter.h"
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ipc/mojo/ipc_channel_mojo.h"
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/handle_enumerator_win.h"
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED)
57bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h"
58bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#endif
59bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using tracked_objects::ThreadData;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// How long to wait for a connection to the browser process before giving up.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kConnectionTimeoutS = 15;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbase::LazyInstance<base::ThreadLocalPointer<ChildThread> > g_lazy_tls =
69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    LAZY_INSTANCE_INITIALIZER;
70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This isn't needed on Windows because there the sandbox's job object
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// terminates child processes automatically. For unsandboxed processes (i.e.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// plugins), PluginThread has EnsureTerminateMessageFilter.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// TODO(earthdok): Re-enable on CrOS http://crbug.com/360622
77c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if (defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \
78c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    defined(THREAD_SANITIZER)) && !defined(OS_CHROMEOS)
79c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// A thread delegate that waits for |duration| and then exits the process with
80c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// _exit(0).
81c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochclass WaitAndExitDelegate : public base::PlatformThread::Delegate {
82c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch public:
83c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  explicit WaitAndExitDelegate(base::TimeDelta duration)
84c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      : duration_(duration) {}
85c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  virtual ~WaitAndExitDelegate() OVERRIDE {}
86c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
87c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  virtual void ThreadMain() OVERRIDE {
88c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    base::PlatformThread::Sleep(duration_);
89c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    _exit(0);
90c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
91c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
92c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch private:
93c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  const base::TimeDelta duration_;
94c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DISALLOW_COPY_AND_ASSIGN(WaitAndExitDelegate);
95c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch};
96c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
97c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool CreateWaitAndExitThread(base::TimeDelta duration) {
98c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_ptr<WaitAndExitDelegate> delegate(new WaitAndExitDelegate(duration));
99c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
100c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  const bool thread_created =
101c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      base::PlatformThread::CreateNonJoinable(0, delegate.get());
102c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!thread_created)
103c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return false;
104c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
105c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // A non joinable thread has been created. The thread will either terminate
106c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // the process or will be terminated by the process. Therefore, keep the
107c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // delegate object alive for the lifetime of the process.
108c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  WaitAndExitDelegate* leaking_delegate = delegate.release();
109c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ANNOTATE_LEAKING_OBJECT_PTR(leaking_delegate);
110c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ignore_result(leaking_delegate);
111c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return true;
112c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
113c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif
114c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass SuicideOnChannelErrorFilter : public IPC::MessageFilter {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // IPC::MessageFilter
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnChannelError() OVERRIDE {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // For renderer/worker processes:
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // On POSIX, at least, one can install an unload handler which loops
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // forever and leave behind a renderer process which eats 100% CPU forever.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This is because the terminate signals (ViewMsg_ShouldClose and the error
124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // from the IPC sender) are routed to the main message loop but never
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // processed (because that message loop is stuck in V8).
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // One could make the browser SIGKILL the renderers, but that leaves open a
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // large window where a browser failure (or a user, manually terminating
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the browser because "it's stuck") will leave behind a process eating all
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the CPU.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // So, we install a filter on the sender so that we can process this event
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // here and kill the process.
134c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // TODO(earthdok): Re-enable on CrOS http://crbug.com/360622
135c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if (defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \
136c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    defined(THREAD_SANITIZER)) && !defined(OS_CHROMEOS)
137c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // Some sanitizer tools rely on exit handlers (e.g. to run leak detection,
138c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // or dump code coverage data to disk). Instead of exiting the process
139c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // immediately, we give it 60 seconds to run exit handlers.
140c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    CHECK(CreateWaitAndExitThread(base::TimeDelta::FromSeconds(60)));
141c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if defined(LEAK_SANITIZER)
142c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // Invoke LeakSanitizer early to avoid detecting shutdown-only leaks. If
143c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // leaks are found, the process will exit here.
144c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    __lsan_do_leak_check();
145c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif
146c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#else
147effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    _exit(0);
148c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SuicideOnChannelErrorFilter() {}
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // OS(POSIX)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_ANDROID)
1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ChildThread* g_child_thread = NULL;
1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// A lock protects g_child_thread.
1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)base::LazyInstance<base::Lock> g_lazy_child_thread_lock =
1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    LAZY_INSTANCE_INITIALIZER;
1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// base::ConditionVariable has an explicit constructor that takes
1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// a base::Lock pointer as parameter. The base::DefaultLazyInstanceTraits
1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// doesn't handle the case. Thus, we need our own class here.
1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)struct CondVarLazyInstanceTraits {
1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  static const bool kRegisterOnExit = true;
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#ifndef NDEBUG
170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static const bool kAllowedToAccessOnNonjoinableThread = false;
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  static base::ConditionVariable* New(void* instance) {
1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return new (instance) base::ConditionVariable(
1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        g_lazy_child_thread_lock.Pointer());
1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  static void Delete(base::ConditionVariable* instance) {
1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    instance->~ConditionVariable();
1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// A condition variable that synchronize threads initializing and waiting
1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// for g_child_thread.
1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)base::LazyInstance<base::ConditionVariable, CondVarLazyInstanceTraits>
1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    g_lazy_child_thread_cv = LAZY_INSTANCE_INITIALIZER;
186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid QuitMainThreadMessageLoop() {
188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::MessageLoop::current()->Quit();
189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)ChildThread::Options::Options()
1966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    : channel_name(base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          switches::kProcessChannelID)),
1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      use_mojo_channel(false) {}
1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)ChildThread::Options::Options(bool mojo)
2016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    : channel_name(base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          switches::kProcessChannelID)),
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      use_mojo_channel(mojo) {}
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ChildThread::ChildThreadMessageRouter::ChildThreadMessageRouter(
207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    IPC::Sender* sender)
208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : sender_(sender) {}
209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ChildThread::ChildThreadMessageRouter::Send(IPC::Message* msg) {
211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return sender_->Send(msg);
212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChildThread::ChildThread()
215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : router_(this),
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      in_browser_process_(false),
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      channel_connected_factory_(this) {
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Init(Options());
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)ChildThread::ChildThread(const Options& options)
2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : router_(this),
2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      in_browser_process_(true),
2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      channel_connected_factory_(this) {
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Init(options);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)scoped_ptr<IPC::SyncChannel> ChildThread::CreateChannel(bool use_mojo_channel) {
2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (use_mojo_channel) {
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    VLOG(1) << "Mojo is enabled on child";
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return IPC::SyncChannel::Create(
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        IPC::ChannelMojo::CreateClientFactory(channel_name_),
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        this,
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        ChildProcess::current()->io_message_loop_proxy(),
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        true,
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        ChildProcess::current()->GetShutDownEvent());
2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  VLOG(1) << "Mojo is disabled on child";
2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return IPC::SyncChannel::Create(
2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      channel_name_,
2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      IPC::Channel::MODE_CLIENT,
2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      this,
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ChildProcess::current()->io_message_loop_proxy(),
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      true,
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ChildProcess::current()->GetShutDownEvent());
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ChildThread::Init(const Options& options) {
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  channel_name_ = options.channel_name;
2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  g_lazy_tls.Pointer()->Set(this);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  on_channel_error_called_ = false;
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop_ = base::MessageLoop::current();
255d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#ifdef IPC_MESSAGE_LOG_ENABLED
256d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // We must make sure to instantiate the IPC Logger *before* we create the
257d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // channel, otherwise we can get a callback on the IO thread which creates
258d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // the logger, and the logger does not like being created on the IO thread.
259d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  IPC::Logging::GetInstance();
260d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif
2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  channel_ = CreateChannel(options.use_mojo_channel);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef IPC_MESSAGE_LOG_ENABLED
2631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!in_browser_process_)
2641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    IPC::Logging::GetInstance()->SetIPCSender(this);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
267116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  mojo_application_.reset(new MojoApplication);
2685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_message_filter_ =
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new IPC::SyncMessageFilter(ChildProcess::current()->GetShutDownEvent());
2717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  thread_safe_sender_ = new ThreadSafeSender(
2727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::MessageLoopProxy::current().get(), sync_message_filter_.get());
273558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
274558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  resource_dispatcher_.reset(new ResourceDispatcher(this));
275558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  socket_stream_dispatcher_.reset(new SocketStreamDispatcher());
27668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  websocket_dispatcher_.reset(new WebSocketDispatcher);
277558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  file_system_dispatcher_.reset(new FileSystemDispatcher());
278558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  histogram_message_filter_ = new ChildHistogramMessageFilter();
280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  resource_message_filter_ =
281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new ChildResourceMessageFilter(resource_dispatcher());
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  service_worker_message_filter_ =
2841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      new ServiceWorkerMessageFilter(thread_safe_sender_.get());
2851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
286558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  quota_message_filter_ =
287558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      new QuotaMessageFilter(thread_safe_sender_.get());
288558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  quota_dispatcher_.reset(new QuotaDispatcher(thread_safe_sender_.get(),
289558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                              quota_message_filter_.get()));
290558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  channel_->AddFilter(histogram_message_filter_.get());
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  channel_->AddFilter(sync_message_filter_.get());
293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  channel_->AddFilter(resource_message_filter_.get());
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  channel_->AddFilter(quota_message_filter_->GetFilter());
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  channel_->AddFilter(service_worker_message_filter_->GetFilter());
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
2986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          switches::kSingleProcess)) {
299116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // In single process mode, browser-side tracing will cover the whole
300116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // process including renderers.
301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    channel_->AddFilter(new tracing::ChildTraceMessageFilter(
302116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        ChildProcess::current()->io_message_loop_proxy()));
303116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
304116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
305a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // In single process mode we may already have a power monitor
306a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!base::PowerMonitor::Get()) {
307a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    scoped_ptr<PowerMonitorBroadcastSource> power_monitor_source(
308a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      new PowerMonitorBroadcastSource());
309a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    channel_->AddFilter(power_monitor_source->GetMessageFilter());
310a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
311a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    power_monitor_.reset(new base::PowerMonitor(
312a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        power_monitor_source.PassAs<base::PowerMonitorSource>()));
313a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
314a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that --process-type is specified so we don't do this in unit tests
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and single-process mode.
3186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessType))
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    channel_->AddFilter(new SuicideOnChannelErrorFilter());
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  int connection_timeout = kConnectionTimeoutS;
3236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  std::string connection_override =
3246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
3256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)          switches::kIPCConnectionTimeout);
3266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (!connection_override.empty()) {
3276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    int temp;
3286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    if (base::StringToInt(connection_override, &temp))
3296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      connection_timeout = temp;
3306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
3316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->PostDelayedTask(
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&ChildThread::EnsureConnected,
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 channel_connected_factory_.GetWeakPtr()),
3366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      base::TimeDelta::FromSeconds(connection_timeout));
337eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
338eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_ANDROID)
3394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  {
3404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    base::AutoLock lock(g_lazy_child_thread_lock.Get());
3414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    g_child_thread = this;
3424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Signalling without locking is fine here because only
3444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // one thread can wait on the condition variable.
3454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  g_lazy_child_thread_cv.Get().Signal();
346eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
347bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
348bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED)
349bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  trace_memory_controller_.reset(new base::debug::TraceMemoryController(
350bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      message_loop_->message_loop_proxy(),
351bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      ::HeapProfilerWithPseudoStackStart,
352bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      ::HeapProfilerStop,
353bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      ::GetHeapProfile));
354bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#endif
355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
356a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  shared_bitmap_manager_.reset(
357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new ChildSharedBitmapManager(thread_safe_sender()));
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChildThread::~ChildThread() {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef IPC_MESSAGE_LOG_ENABLED
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC::Logging::GetInstance()->SetIPCSender(NULL);
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  channel_->RemoveFilter(histogram_message_filter_.get());
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  channel_->RemoveFilter(sync_message_filter_.get());
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The ChannelProxy object caches a pointer to the IPC thread, so need to
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // reset it as it's not guaranteed to outlive this object.
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: this also has the side-effect of not closing the main IPC channel to
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the browser process.  This is needed because this is the signal that the
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // browser uses to know that this process has died, so we need it to be alive
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // until this process is shut down, and the OS closes the handle
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // automatically.  We used to watch the object handle on Windows to do this,
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // but it wasn't possible to do so on POSIX.
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  channel_->ClearIPCTaskRunner();
377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  g_lazy_tls.Pointer()->Set(NULL);
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
380a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid ChildThread::Shutdown() {
381a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  // Delete objects that hold references to blink so derived classes can
382a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  // safely shutdown blink in their Shutdown implementation.
383a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  file_system_dispatcher_.reset();
384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  quota_dispatcher_.reset();
3850de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  WebFileSystemImpl::DeleteThreadSpecificInstance();
386a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
387a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChildThread::OnChannelConnected(int32 peer_pid) {
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  channel_connected_factory_.InvalidateWeakPtrs();
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChildThread::OnChannelError() {
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set_on_channel_error_called(true);
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->Quit();
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChildThread::Send(IPC::Message* msg) {
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(base::MessageLoop::current() == message_loop());
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!channel_) {
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete msg;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return channel_->Send(msg);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
407a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)MessageRouter* ChildThread::GetRouter() {
408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(base::MessageLoop::current() == message_loop());
409a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return &router_;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::SharedMemory* ChildThread::AllocateSharedMemory(size_t buf_size) {
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return AllocateSharedMemory(buf_size, this);
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::SharedMemory* ChildThread::AllocateSharedMemory(
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t buf_size,
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC::Sender* sender) {
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::SharedMemory> shared_buf;
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  shared_buf.reset(new base::SharedMemory);
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!shared_buf->CreateAndMapAnonymous(buf_size)) {
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // On POSIX, we need to ask the browser to create the shared memory for us,
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // since this is blocked by the sandbox.
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::SharedMemoryHandle shared_mem_handle;
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (sender->Send(new ChildProcessHostMsg_SyncAllocateSharedMemory(
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           buf_size, &shared_mem_handle))) {
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (base::SharedMemory::IsHandleValid(shared_mem_handle)) {
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shared_buf.reset(new base::SharedMemory(shared_mem_handle, false));
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!shared_buf->Map(buf_size)) {
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED() << "Map failed";
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return NULL;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED() << "Browser failed to allocate shared memory";
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return NULL;
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "Browser allocation request message failed";
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return shared_buf.release();
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChildThread::OnMessageReceived(const IPC::Message& msg) {
4525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (mojo_application_->OnMessageReceived(msg))
4535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return true;
4545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Resource responses are sent to the resource dispatcher.
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (resource_dispatcher_->OnMessageReceived(msg))
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (socket_stream_dispatcher_->OnMessageReceived(msg))
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
46068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (websocket_dispatcher_->OnMessageReceived(msg))
46168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return true;
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (file_system_dispatcher_->OnMessageReceived(msg))
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handled = true;
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(ChildThread, msg)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChildProcessMsg_Shutdown, OnShutdown)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(IPC_MESSAGE_LOG_ENABLED)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChildProcessMsg_SetIPCLoggingEnabled,
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnSetIPCLoggingEnabled)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChildProcessMsg_SetProfilerStatus,
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnSetProfilerStatus)
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChildProcessMsg_GetChildProfilerData,
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnGetChildProfilerData)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChildProcessMsg_DumpHandles, OnDumpHandles)
4776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChildProcessMsg_SetProcessBackgrounded,
4786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                        OnProcessBackgrounded)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_TCMALLOC)
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChildProcessMsg_GetTcmallocStats, OnGetTcmallocStats)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (handled)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (msg.routing_id() == MSG_ROUTING_CONTROL)
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OnControlMessageReceived(msg);
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return router_.OnMessageReceived(msg);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChildThread::OnControlMessageReceived(const IPC::Message& msg) {
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChildThread::OnShutdown() {
499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->Quit();
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(IPC_MESSAGE_LOG_ENABLED)
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChildThread::OnSetIPCLoggingEnabled(bool enable) {
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (enable)
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC::Logging::GetInstance()->Enable();
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC::Logging::GetInstance()->Disable();
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  //  IPC_MESSAGE_LOG_ENABLED
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChildThread::OnSetProfilerStatus(ThreadData::Status status) {
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ThreadData::InitializeAndSetTrackingStatus(status);
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChildThread::OnGetChildProfilerData(int sequence_number) {
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tracked_objects::ProcessDataSnapshot process_data;
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ThreadData::Snapshot(false, &process_data);
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new ChildProcessHostMsg_ChildProfilerData(sequence_number,
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 process_data));
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChildThread::OnDumpHandles() {
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HandleEnumerator> handle_enum(
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new HandleEnumerator(
5276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          base::CommandLine::ForCurrentProcess()->HasSwitch(
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              switches::kAuditAllHandles)));
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handle_enum->EnumerateHandles();
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new ChildProcessHostMsg_DumpHandlesDone);
53123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#else
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTIMPLEMENTED();
53323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#endif
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_TCMALLOC)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChildThread::OnGetTcmallocStats() {
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string result;
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char buffer[1024 * 32];
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::allocator::GetStats(buffer, sizeof(buffer));
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.append(buffer);
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new ChildProcessHostMsg_TcmallocStats(result));
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChildThread* ChildThread::current() {
547eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return g_lazy_tls.Pointer()->Get();
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
550eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_ANDROID)
5514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// The method must NOT be called on the child thread itself.
5524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// It may block the child thread if so.
553eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ChildThread::ShutdownThread() {
5544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!ChildThread::current()) <<
5554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      "this method should NOT be called from child thread itself";
5564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  {
5574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    base::AutoLock lock(g_lazy_child_thread_lock.Get());
5584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    while (!g_child_thread)
5594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      g_lazy_child_thread_cv.Get().Wait();
5604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
561eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK_NE(base::MessageLoop::current(), g_child_thread->message_loop());
562eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  g_child_thread->message_loop()->PostTask(
563eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE, base::Bind(&QuitMainThreadMessageLoop));
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
565eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
566eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChildThread::OnProcessFinalRelease() {
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (on_channel_error_called_) {
569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::MessageLoop::current()->Quit();
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The child process shutdown sequence is a request response based mechanism,
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // where we send out an initial feeler request to the child process host
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // instance in the browser to verify if it's ok to shutdown the child process.
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The browser then sends back a response if it's ok to shutdown. This avoids
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // race conditions if the process refcount is 0 but there's an IPC message
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // inflight that would addref it.
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new ChildProcessHostMsg_ShutdownRequest);
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChildThread::EnsureConnected() {
583f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VLOG(0) << "ChildThread::EnsureConnected()";
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::KillProcess(base::GetCurrentProcessHandle(), 0, false);
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ChildThread::OnProcessBackgrounded(bool background) {
5886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Set timer slack to maximum on main thread when in background.
5896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  base::TimerSlack timer_slack = base::TIMER_SLACK_NONE;
5906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (background)
5916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    timer_slack = base::TIMER_SLACK_MAXIMUM;
5926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  base::MessageLoop::current()->SetTimerSlack(timer_slack);
5936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
5946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
596