Home | History | Annotate | Download | only in worker
      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/worker/worker_thread.h"
      6 
      7 #include "base/command_line.h"
      8 #include "base/lazy_instance.h"
      9 #include "base/threading/thread_local.h"
     10 #include "content/child/appcache/appcache_dispatcher.h"
     11 #include "content/child/appcache/appcache_frontend_impl.h"
     12 #include "content/child/db_message_filter.h"
     13 #include "content/child/indexed_db/indexed_db_message_filter.h"
     14 #include "content/child/runtime_features.h"
     15 #include "content/child/web_database_observer_impl.h"
     16 #include "content/common/child_process_messages.h"
     17 #include "content/common/worker_messages.h"
     18 #include "content/public/common/content_switches.h"
     19 #include "content/worker/websharedworker_stub.h"
     20 #include "content/worker/worker_webkitplatformsupport_impl.h"
     21 #include "ipc/ipc_sync_channel.h"
     22 #include "third_party/WebKit/public/platform/WebBlobRegistry.h"
     23 #include "third_party/WebKit/public/web/WebDatabase.h"
     24 #include "third_party/WebKit/public/web/WebKit.h"
     25 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
     26 #include "v8/include/v8.h"
     27 
     28 using blink::WebRuntimeFeatures;
     29 
     30 namespace content {
     31 
     32 static base::LazyInstance<base::ThreadLocalPointer<WorkerThread> > lazy_tls =
     33     LAZY_INSTANCE_INITIALIZER;
     34 
     35 WorkerThread::WorkerThread() {
     36   lazy_tls.Pointer()->Set(this);
     37   webkit_platform_support_.reset(new WorkerWebKitPlatformSupportImpl(
     38       thread_safe_sender(),
     39       sync_message_filter(),
     40       quota_message_filter()));
     41 
     42   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
     43   if (command_line.HasSwitch(switches::kJavaScriptFlags)) {
     44     std::string flags(
     45         command_line.GetSwitchValueASCII(switches::kJavaScriptFlags));
     46     v8::V8::SetFlagsFromString(flags.c_str(), static_cast<int>(flags.size()));
     47   }
     48   SetRuntimeFeaturesDefaultsAndUpdateFromArgs(command_line);
     49 
     50   blink::initialize(webkit_platform_support_.get());
     51 
     52   appcache_dispatcher_.reset(
     53       new AppCacheDispatcher(this, new AppCacheFrontendImpl()));
     54 
     55   db_message_filter_ = new DBMessageFilter();
     56   channel()->AddFilter(db_message_filter_.get());
     57 
     58   indexed_db_message_filter_ = new IndexedDBMessageFilter(
     59       thread_safe_sender());
     60   channel()->AddFilter(indexed_db_message_filter_->GetFilter());
     61 
     62 }
     63 
     64 void WorkerThread::OnShutdown() {
     65   // The worker process is to be shut down gracefully. Ask the browser
     66   // process to shut it down forcefully instead and wait on the message, so that
     67   // there are no races between threads when the process is shutting down.
     68   Send(new WorkerProcessHostMsg_ForceKillWorker());
     69 }
     70 
     71 WorkerThread::~WorkerThread() {
     72 }
     73 
     74 void WorkerThread::Shutdown() {
     75   ChildThread::Shutdown();
     76 
     77   if (webkit_platform_support_) {
     78     webkit_platform_support_->web_database_observer_impl()->
     79         WaitForAllDatabasesToClose();
     80   }
     81 
     82   // Shutdown in reverse of the initialization order.
     83   indexed_db_message_filter_ = NULL;
     84 
     85   channel()->RemoveFilter(db_message_filter_.get());
     86   db_message_filter_ = NULL;
     87 
     88   blink::shutdown();
     89   lazy_tls.Pointer()->Set(NULL);
     90 }
     91 
     92 WorkerThread* WorkerThread::current() {
     93   return lazy_tls.Pointer()->Get();
     94 }
     95 
     96 bool WorkerThread::OnControlMessageReceived(const IPC::Message& msg) {
     97   // Appcache messages are handled by a delegate.
     98   if (appcache_dispatcher_->OnMessageReceived(msg))
     99     return true;
    100 
    101   bool handled = true;
    102   IPC_BEGIN_MESSAGE_MAP(WorkerThread, msg)
    103     IPC_MESSAGE_HANDLER(WorkerProcessMsg_CreateWorker, OnCreateWorker)
    104     IPC_MESSAGE_UNHANDLED(handled = false)
    105   IPC_END_MESSAGE_MAP()
    106   return handled;
    107 }
    108 
    109 bool WorkerThread::OnMessageReceived(const IPC::Message& msg) {
    110   bool handled = true;
    111   IPC_BEGIN_MESSAGE_MAP(WorkerThread, msg)
    112     IPC_MESSAGE_HANDLER(ChildProcessMsg_Shutdown, OnShutdown)
    113     IPC_MESSAGE_UNHANDLED(handled = ChildThread::OnMessageReceived(msg))
    114   IPC_END_MESSAGE_MAP()
    115   return handled;
    116 }
    117 
    118 void WorkerThread::OnCreateWorker(
    119     const WorkerProcessMsg_CreateWorker_Params& params) {
    120   // WebSharedWorkerStub own themselves.
    121   new WebSharedWorkerStub(
    122       params.url,
    123       params.name,
    124       params.content_security_policy,
    125       params.security_policy_type,
    126       params.pause_on_start,
    127       params.route_id);
    128 }
    129 
    130 // The browser process is likely dead. Terminate all workers.
    131 void WorkerThread::OnChannelError() {
    132   set_on_channel_error_called(true);
    133 
    134   for (WorkerStubsList::iterator it = worker_stubs_.begin();
    135        it != worker_stubs_.end(); ++it) {
    136     (*it)->OnChannelError();
    137   }
    138 }
    139 
    140 void WorkerThread::RemoveWorkerStub(WebSharedWorkerStub* stub) {
    141   worker_stubs_.erase(stub);
    142 }
    143 
    144 void WorkerThread::AddWorkerStub(WebSharedWorkerStub* stub) {
    145   worker_stubs_.insert(stub);
    146 }
    147 
    148 }  // namespace content
    149