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