Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / content / child / child_thread.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/child/child_thread.h"
6
7 #include <signal.h>
8
9 #include <string>
10
11 #include "base/allocator/allocator_extension.h"
12 #include "base/base_switches.h"
13 #include "base/basictypes.h"
14 #include "base/command_line.h"
15 #include "base/debug/leak_annotations.h"
16 #include "base/lazy_instance.h"
17 #include "base/logging.h"
18 #include "base/message_loop/message_loop.h"
19 #include "base/message_loop/timer_slack.h"
20 #include "base/process/kill.h"
21 #include "base/process/process_handle.h"
22 #include "base/strings/string_number_conversions.h"
23 #include "base/strings/string_util.h"
24 #include "base/synchronization/condition_variable.h"
25 #include "base/synchronization/lock.h"
26 #include "base/threading/thread_local.h"
27 #include "base/tracked_objects.h"
28 #include "components/tracing/child_trace_message_filter.h"
29 #include "content/child/child_histogram_message_filter.h"
30 #include "content/child/child_process.h"
31 #include "content/child/child_resource_message_filter.h"
32 #include "content/child/child_shared_bitmap_manager.h"
33 #include "content/child/fileapi/file_system_dispatcher.h"
34 #include "content/child/fileapi/webfilesystem_impl.h"
35 #include "content/child/mojo/mojo_application.h"
36 #include "content/child/power_monitor_broadcast_source.h"
37 #include "content/child/quota_dispatcher.h"
38 #include "content/child/quota_message_filter.h"
39 #include "content/child/resource_dispatcher.h"
40 #include "content/child/service_worker/service_worker_message_filter.h"
41 #include "content/child/socket_stream_dispatcher.h"
42 #include "content/child/thread_safe_sender.h"
43 #include "content/child/websocket_dispatcher.h"
44 #include "content/common/child_process_messages.h"
45 #include "content/public/common/content_switches.h"
46 #include "ipc/ipc_logging.h"
47 #include "ipc/ipc_switches.h"
48 #include "ipc/ipc_sync_channel.h"
49 #include "ipc/ipc_sync_message_filter.h"
50 #include "ipc/mojo/ipc_channel_mojo.h"
51
52 #if defined(OS_WIN)
53 #include "content/common/handle_enumerator_win.h"
54 #endif
55
56 #if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED)
57 #include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h"
58 #endif
59
60 using tracked_objects::ThreadData;
61
62 namespace content {
63 namespace {
64
65 // How long to wait for a connection to the browser process before giving up.
66 const int kConnectionTimeoutS = 15;
67
68 base::LazyInstance<base::ThreadLocalPointer<ChildThread> > g_lazy_tls =
69     LAZY_INSTANCE_INITIALIZER;
70
71 // This isn't needed on Windows because there the sandbox's job object
72 // terminates child processes automatically. For unsandboxed processes (i.e.
73 // plugins), PluginThread has EnsureTerminateMessageFilter.
74 #if defined(OS_POSIX)
75
76 // TODO(earthdok): Re-enable on CrOS http://crbug.com/360622
77 #if (defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \
78     defined(THREAD_SANITIZER)) && !defined(OS_CHROMEOS)
79 // A thread delegate that waits for |duration| and then exits the process with
80 // _exit(0).
81 class WaitAndExitDelegate : public base::PlatformThread::Delegate {
82  public:
83   explicit WaitAndExitDelegate(base::TimeDelta duration)
84       : duration_(duration) {}
85   virtual ~WaitAndExitDelegate() OVERRIDE {}
86
87   virtual void ThreadMain() OVERRIDE {
88     base::PlatformThread::Sleep(duration_);
89     _exit(0);
90   }
91
92  private:
93   const base::TimeDelta duration_;
94   DISALLOW_COPY_AND_ASSIGN(WaitAndExitDelegate);
95 };
96
97 bool CreateWaitAndExitThread(base::TimeDelta duration) {
98   scoped_ptr<WaitAndExitDelegate> delegate(new WaitAndExitDelegate(duration));
99
100   const bool thread_created =
101       base::PlatformThread::CreateNonJoinable(0, delegate.get());
102   if (!thread_created)
103     return false;
104
105   // A non joinable thread has been created. The thread will either terminate
106   // the process or will be terminated by the process. Therefore, keep the
107   // delegate object alive for the lifetime of the process.
108   WaitAndExitDelegate* leaking_delegate = delegate.release();
109   ANNOTATE_LEAKING_OBJECT_PTR(leaking_delegate);
110   ignore_result(leaking_delegate);
111   return true;
112 }
113 #endif
114
115 class SuicideOnChannelErrorFilter : public IPC::MessageFilter {
116  public:
117   // IPC::MessageFilter
118   virtual void OnChannelError() OVERRIDE {
119     // For renderer/worker processes:
120     // On POSIX, at least, one can install an unload handler which loops
121     // forever and leave behind a renderer process which eats 100% CPU forever.
122     //
123     // This is because the terminate signals (ViewMsg_ShouldClose and the error
124     // from the IPC sender) are routed to the main message loop but never
125     // processed (because that message loop is stuck in V8).
126     //
127     // One could make the browser SIGKILL the renderers, but that leaves open a
128     // large window where a browser failure (or a user, manually terminating
129     // the browser because "it's stuck") will leave behind a process eating all
130     // the CPU.
131     //
132     // So, we install a filter on the sender so that we can process this event
133     // here and kill the process.
134     // TODO(earthdok): Re-enable on CrOS http://crbug.com/360622
135 #if (defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \
136     defined(THREAD_SANITIZER)) && !defined(OS_CHROMEOS)
137     // Some sanitizer tools rely on exit handlers (e.g. to run leak detection,
138     // or dump code coverage data to disk). Instead of exiting the process
139     // immediately, we give it 60 seconds to run exit handlers.
140     CHECK(CreateWaitAndExitThread(base::TimeDelta::FromSeconds(60)));
141 #if defined(LEAK_SANITIZER)
142     // Invoke LeakSanitizer early to avoid detecting shutdown-only leaks. If
143     // leaks are found, the process will exit here.
144     __lsan_do_leak_check();
145 #endif
146 #else
147     _exit(0);
148 #endif
149   }
150
151  protected:
152   virtual ~SuicideOnChannelErrorFilter() {}
153 };
154
155 #endif  // OS(POSIX)
156
157 #if defined(OS_ANDROID)
158 ChildThread* g_child_thread = NULL;
159
160 // A lock protects g_child_thread.
161 base::LazyInstance<base::Lock> g_lazy_child_thread_lock =
162     LAZY_INSTANCE_INITIALIZER;
163
164 // base::ConditionVariable has an explicit constructor that takes
165 // a base::Lock pointer as parameter. The base::DefaultLazyInstanceTraits
166 // doesn't handle the case. Thus, we need our own class here.
167 struct CondVarLazyInstanceTraits {
168   static const bool kRegisterOnExit = true;
169 #ifndef NDEBUG
170   static const bool kAllowedToAccessOnNonjoinableThread = false;
171 #endif
172
173   static base::ConditionVariable* New(void* instance) {
174     return new (instance) base::ConditionVariable(
175         g_lazy_child_thread_lock.Pointer());
176   }
177   static void Delete(base::ConditionVariable* instance) {
178     instance->~ConditionVariable();
179   }
180 };
181
182 // A condition variable that synchronize threads initializing and waiting
183 // for g_child_thread.
184 base::LazyInstance<base::ConditionVariable, CondVarLazyInstanceTraits>
185     g_lazy_child_thread_cv = LAZY_INSTANCE_INITIALIZER;
186
187 void QuitMainThreadMessageLoop() {
188   base::MessageLoop::current()->Quit();
189 }
190
191 #endif
192
193 }  // namespace
194
195 ChildThread::Options::Options()
196     : channel_name(base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
197           switches::kProcessChannelID)),
198       use_mojo_channel(false) {}
199
200 ChildThread::Options::Options(bool mojo)
201     : channel_name(base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
202           switches::kProcessChannelID)),
203       use_mojo_channel(mojo) {}
204
205
206 ChildThread::ChildThreadMessageRouter::ChildThreadMessageRouter(
207     IPC::Sender* sender)
208     : sender_(sender) {}
209
210 bool ChildThread::ChildThreadMessageRouter::Send(IPC::Message* msg) {
211   return sender_->Send(msg);
212 }
213
214 ChildThread::ChildThread()
215     : router_(this),
216       channel_connected_factory_(this),
217       in_browser_process_(false) {
218   Init(Options());
219 }
220
221 ChildThread::ChildThread(const Options& options)
222     : router_(this),
223       channel_connected_factory_(this),
224       in_browser_process_(true) {
225   Init(options);
226 }
227
228 scoped_ptr<IPC::SyncChannel> ChildThread::CreateChannel(bool use_mojo_channel) {
229   if (use_mojo_channel) {
230     VLOG(1) << "Mojo is enabled on child";
231     return IPC::SyncChannel::Create(
232         IPC::ChannelMojo::CreateFactory(
233             channel_name_,
234             IPC::Channel::MODE_CLIENT,
235             ChildProcess::current()->io_message_loop_proxy()),
236         this,
237         ChildProcess::current()->io_message_loop_proxy(),
238         true,
239         ChildProcess::current()->GetShutDownEvent());
240   }
241
242   VLOG(1) << "Mojo is disabled on child";
243   return IPC::SyncChannel::Create(
244       channel_name_,
245       IPC::Channel::MODE_CLIENT,
246       this,
247       ChildProcess::current()->io_message_loop_proxy(),
248       true,
249       ChildProcess::current()->GetShutDownEvent());
250 }
251
252 void ChildThread::Init(const Options& options) {
253   channel_name_ = options.channel_name;
254
255   g_lazy_tls.Pointer()->Set(this);
256   on_channel_error_called_ = false;
257   message_loop_ = base::MessageLoop::current();
258 #ifdef IPC_MESSAGE_LOG_ENABLED
259   // We must make sure to instantiate the IPC Logger *before* we create the
260   // channel, otherwise we can get a callback on the IO thread which creates
261   // the logger, and the logger does not like being created on the IO thread.
262   IPC::Logging::GetInstance();
263 #endif
264   channel_ = CreateChannel(options.use_mojo_channel);
265 #ifdef IPC_MESSAGE_LOG_ENABLED
266   if (!in_browser_process_)
267     IPC::Logging::GetInstance()->SetIPCSender(this);
268 #endif
269
270   mojo_application_.reset(new MojoApplication);
271
272   sync_message_filter_ =
273       new IPC::SyncMessageFilter(ChildProcess::current()->GetShutDownEvent());
274   thread_safe_sender_ = new ThreadSafeSender(
275       base::MessageLoopProxy::current().get(), sync_message_filter_.get());
276
277   resource_dispatcher_.reset(new ResourceDispatcher(this));
278   socket_stream_dispatcher_.reset(new SocketStreamDispatcher());
279   websocket_dispatcher_.reset(new WebSocketDispatcher);
280   file_system_dispatcher_.reset(new FileSystemDispatcher());
281
282   histogram_message_filter_ = new ChildHistogramMessageFilter();
283   resource_message_filter_ =
284       new ChildResourceMessageFilter(resource_dispatcher());
285
286   service_worker_message_filter_ =
287       new ServiceWorkerMessageFilter(thread_safe_sender_.get());
288
289   quota_message_filter_ =
290       new QuotaMessageFilter(thread_safe_sender_.get());
291   quota_dispatcher_.reset(new QuotaDispatcher(thread_safe_sender_.get(),
292                                               quota_message_filter_.get()));
293
294   channel_->AddFilter(histogram_message_filter_.get());
295   channel_->AddFilter(sync_message_filter_.get());
296   channel_->AddFilter(resource_message_filter_.get());
297   channel_->AddFilter(quota_message_filter_->GetFilter());
298   channel_->AddFilter(service_worker_message_filter_->GetFilter());
299
300   if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
301           switches::kSingleProcess)) {
302     // In single process mode, browser-side tracing will cover the whole
303     // process including renderers.
304     channel_->AddFilter(new tracing::ChildTraceMessageFilter(
305         ChildProcess::current()->io_message_loop_proxy()));
306   }
307
308   // In single process mode we may already have a power monitor
309   if (!base::PowerMonitor::Get()) {
310     scoped_ptr<PowerMonitorBroadcastSource> power_monitor_source(
311       new PowerMonitorBroadcastSource());
312     channel_->AddFilter(power_monitor_source->GetMessageFilter());
313
314     power_monitor_.reset(new base::PowerMonitor(
315         power_monitor_source.PassAs<base::PowerMonitorSource>()));
316   }
317
318 #if defined(OS_POSIX)
319   // Check that --process-type is specified so we don't do this in unit tests
320   // and single-process mode.
321   if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessType))
322     channel_->AddFilter(new SuicideOnChannelErrorFilter());
323 #endif
324
325   int connection_timeout = kConnectionTimeoutS;
326   std::string connection_override =
327       base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
328           switches::kIPCConnectionTimeout);
329   if (!connection_override.empty()) {
330     int temp;
331     if (base::StringToInt(connection_override, &temp))
332       connection_timeout = temp;
333   }
334
335   base::MessageLoop::current()->PostDelayedTask(
336       FROM_HERE,
337       base::Bind(&ChildThread::EnsureConnected,
338                  channel_connected_factory_.GetWeakPtr()),
339       base::TimeDelta::FromSeconds(connection_timeout));
340
341 #if defined(OS_ANDROID)
342   {
343     base::AutoLock lock(g_lazy_child_thread_lock.Get());
344     g_child_thread = this;
345   }
346   // Signalling without locking is fine here because only
347   // one thread can wait on the condition variable.
348   g_lazy_child_thread_cv.Get().Signal();
349 #endif
350
351 #if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED)
352   trace_memory_controller_.reset(new base::debug::TraceMemoryController(
353       message_loop_->message_loop_proxy(),
354       ::HeapProfilerWithPseudoStackStart,
355       ::HeapProfilerStop,
356       ::GetHeapProfile));
357 #endif
358
359   shared_bitmap_manager_.reset(
360       new ChildSharedBitmapManager(thread_safe_sender()));
361 }
362
363 ChildThread::~ChildThread() {
364 #ifdef IPC_MESSAGE_LOG_ENABLED
365   IPC::Logging::GetInstance()->SetIPCSender(NULL);
366 #endif
367
368   channel_->RemoveFilter(histogram_message_filter_.get());
369   channel_->RemoveFilter(sync_message_filter_.get());
370
371   // The ChannelProxy object caches a pointer to the IPC thread, so need to
372   // reset it as it's not guaranteed to outlive this object.
373   // NOTE: this also has the side-effect of not closing the main IPC channel to
374   // the browser process.  This is needed because this is the signal that the
375   // browser uses to know that this process has died, so we need it to be alive
376   // until this process is shut down, and the OS closes the handle
377   // automatically.  We used to watch the object handle on Windows to do this,
378   // but it wasn't possible to do so on POSIX.
379   channel_->ClearIPCTaskRunner();
380   g_lazy_tls.Pointer()->Set(NULL);
381 }
382
383 void ChildThread::Shutdown() {
384   // Delete objects that hold references to blink so derived classes can
385   // safely shutdown blink in their Shutdown implementation.
386   file_system_dispatcher_.reset();
387   quota_dispatcher_.reset();
388   WebFileSystemImpl::DeleteThreadSpecificInstance();
389 }
390
391 void ChildThread::OnChannelConnected(int32 peer_pid) {
392   channel_connected_factory_.InvalidateWeakPtrs();
393 }
394
395 void ChildThread::OnChannelError() {
396   set_on_channel_error_called(true);
397   base::MessageLoop::current()->Quit();
398 }
399
400 bool ChildThread::Send(IPC::Message* msg) {
401   DCHECK(base::MessageLoop::current() == message_loop());
402   if (!channel_) {
403     delete msg;
404     return false;
405   }
406
407   return channel_->Send(msg);
408 }
409
410 MessageRouter* ChildThread::GetRouter() {
411   DCHECK(base::MessageLoop::current() == message_loop());
412   return &router_;
413 }
414
415 base::SharedMemory* ChildThread::AllocateSharedMemory(size_t buf_size) {
416   return AllocateSharedMemory(buf_size, this);
417 }
418
419 // static
420 base::SharedMemory* ChildThread::AllocateSharedMemory(
421     size_t buf_size,
422     IPC::Sender* sender) {
423   scoped_ptr<base::SharedMemory> shared_buf;
424 #if defined(OS_WIN)
425   shared_buf.reset(new base::SharedMemory);
426   if (!shared_buf->CreateAndMapAnonymous(buf_size)) {
427     NOTREACHED();
428     return NULL;
429   }
430 #else
431   // On POSIX, we need to ask the browser to create the shared memory for us,
432   // since this is blocked by the sandbox.
433   base::SharedMemoryHandle shared_mem_handle;
434   if (sender->Send(new ChildProcessHostMsg_SyncAllocateSharedMemory(
435                            buf_size, &shared_mem_handle))) {
436     if (base::SharedMemory::IsHandleValid(shared_mem_handle)) {
437       shared_buf.reset(new base::SharedMemory(shared_mem_handle, false));
438       if (!shared_buf->Map(buf_size)) {
439         NOTREACHED() << "Map failed";
440         return NULL;
441       }
442     } else {
443       NOTREACHED() << "Browser failed to allocate shared memory";
444       return NULL;
445     }
446   } else {
447     NOTREACHED() << "Browser allocation request message failed";
448     return NULL;
449   }
450 #endif
451   return shared_buf.release();
452 }
453
454 bool ChildThread::OnMessageReceived(const IPC::Message& msg) {
455   if (mojo_application_->OnMessageReceived(msg))
456     return true;
457
458   // Resource responses are sent to the resource dispatcher.
459   if (resource_dispatcher_->OnMessageReceived(msg))
460     return true;
461   if (socket_stream_dispatcher_->OnMessageReceived(msg))
462     return true;
463   if (websocket_dispatcher_->OnMessageReceived(msg))
464     return true;
465   if (file_system_dispatcher_->OnMessageReceived(msg))
466     return true;
467
468   bool handled = true;
469   IPC_BEGIN_MESSAGE_MAP(ChildThread, msg)
470     IPC_MESSAGE_HANDLER(ChildProcessMsg_Shutdown, OnShutdown)
471 #if defined(IPC_MESSAGE_LOG_ENABLED)
472     IPC_MESSAGE_HANDLER(ChildProcessMsg_SetIPCLoggingEnabled,
473                         OnSetIPCLoggingEnabled)
474 #endif
475     IPC_MESSAGE_HANDLER(ChildProcessMsg_SetProfilerStatus,
476                         OnSetProfilerStatus)
477     IPC_MESSAGE_HANDLER(ChildProcessMsg_GetChildProfilerData,
478                         OnGetChildProfilerData)
479     IPC_MESSAGE_HANDLER(ChildProcessMsg_DumpHandles, OnDumpHandles)
480     IPC_MESSAGE_HANDLER(ChildProcessMsg_SetProcessBackgrounded,
481                         OnProcessBackgrounded)
482 #if defined(USE_TCMALLOC)
483     IPC_MESSAGE_HANDLER(ChildProcessMsg_GetTcmallocStats, OnGetTcmallocStats)
484 #endif
485     IPC_MESSAGE_UNHANDLED(handled = false)
486   IPC_END_MESSAGE_MAP()
487
488   if (handled)
489     return true;
490
491   if (msg.routing_id() == MSG_ROUTING_CONTROL)
492     return OnControlMessageReceived(msg);
493
494   return router_.OnMessageReceived(msg);
495 }
496
497 bool ChildThread::OnControlMessageReceived(const IPC::Message& msg) {
498   return false;
499 }
500
501 void ChildThread::OnShutdown() {
502   base::MessageLoop::current()->Quit();
503 }
504
505 #if defined(IPC_MESSAGE_LOG_ENABLED)
506 void ChildThread::OnSetIPCLoggingEnabled(bool enable) {
507   if (enable)
508     IPC::Logging::GetInstance()->Enable();
509   else
510     IPC::Logging::GetInstance()->Disable();
511 }
512 #endif  //  IPC_MESSAGE_LOG_ENABLED
513
514 void ChildThread::OnSetProfilerStatus(ThreadData::Status status) {
515   ThreadData::InitializeAndSetTrackingStatus(status);
516 }
517
518 void ChildThread::OnGetChildProfilerData(int sequence_number) {
519   tracked_objects::ProcessDataSnapshot process_data;
520   ThreadData::Snapshot(false, &process_data);
521
522   Send(new ChildProcessHostMsg_ChildProfilerData(sequence_number,
523                                                  process_data));
524 }
525
526 void ChildThread::OnDumpHandles() {
527 #if defined(OS_WIN)
528   scoped_refptr<HandleEnumerator> handle_enum(
529       new HandleEnumerator(
530           base::CommandLine::ForCurrentProcess()->HasSwitch(
531               switches::kAuditAllHandles)));
532   handle_enum->EnumerateHandles();
533   Send(new ChildProcessHostMsg_DumpHandlesDone);
534 #else
535   NOTIMPLEMENTED();
536 #endif
537 }
538
539 #if defined(USE_TCMALLOC)
540 void ChildThread::OnGetTcmallocStats() {
541   std::string result;
542   char buffer[1024 * 32];
543   base::allocator::GetStats(buffer, sizeof(buffer));
544   result.append(buffer);
545   Send(new ChildProcessHostMsg_TcmallocStats(result));
546 }
547 #endif
548
549 ChildThread* ChildThread::current() {
550   return g_lazy_tls.Pointer()->Get();
551 }
552
553 #if defined(OS_ANDROID)
554 // The method must NOT be called on the child thread itself.
555 // It may block the child thread if so.
556 void ChildThread::ShutdownThread() {
557   DCHECK(!ChildThread::current()) <<
558       "this method should NOT be called from child thread itself";
559   {
560     base::AutoLock lock(g_lazy_child_thread_lock.Get());
561     while (!g_child_thread)
562       g_lazy_child_thread_cv.Get().Wait();
563   }
564   DCHECK_NE(base::MessageLoop::current(), g_child_thread->message_loop());
565   g_child_thread->message_loop()->PostTask(
566       FROM_HERE, base::Bind(&QuitMainThreadMessageLoop));
567 }
568 #endif
569
570 void ChildThread::OnProcessFinalRelease() {
571   if (on_channel_error_called_) {
572     base::MessageLoop::current()->Quit();
573     return;
574   }
575
576   // The child process shutdown sequence is a request response based mechanism,
577   // where we send out an initial feeler request to the child process host
578   // instance in the browser to verify if it's ok to shutdown the child process.
579   // The browser then sends back a response if it's ok to shutdown. This avoids
580   // race conditions if the process refcount is 0 but there's an IPC message
581   // inflight that would addref it.
582   Send(new ChildProcessHostMsg_ShutdownRequest);
583 }
584
585 void ChildThread::EnsureConnected() {
586   VLOG(0) << "ChildThread::EnsureConnected()";
587   base::KillProcess(base::GetCurrentProcessHandle(), 0, false);
588 }
589
590 void ChildThread::OnProcessBackgrounded(bool background) {
591   // Set timer slack to maximum on main thread when in background.
592   base::TimerSlack timer_slack = base::TIMER_SLACK_NONE;
593   if (background)
594     timer_slack = base::TIMER_SLACK_MAXIMUM;
595   base::MessageLoop::current()->SetTimerSlack(timer_slack);
596 }
597
598 }  // namespace content