Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2014 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/service_worker/service_worker_provider_context.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/message_loop/message_loop_proxy.h" | |
| 9 #include "base/stl_util.h" | |
| 10 #include "content/child/child_thread.h" | |
| 11 #include "content/child/service_worker/scoped_service_worker_reference.h" | |
| 12 #include "content/child/service_worker/service_worker_dispatcher.h" | |
| 13 #include "content/child/thread_safe_sender.h" | |
| 14 #include "content/child/worker_task_runner.h" | |
| 15 #include "content/common/service_worker/service_worker_messages.h" | |
| 16 | |
| 17 namespace content { | |
| 18 | |
| 19 namespace { | |
| 20 | |
| 21 void ForwardMessage(scoped_ptr<IPC::Message> message) { | |
| 22 if (ServiceWorkerDispatcher* dispatcher = | |
| 23 ServiceWorkerDispatcher::GetThreadSpecificInstance()) { | |
| 24 dispatcher->OnMessageReceived(*message); | |
| 25 } | |
| 26 } | |
| 27 | |
| 28 } // namespace | |
| 29 | |
| 30 ServiceWorkerProviderContext::ServiceWorkerProviderContext(int provider_id) | |
| 31 : provider_id_(provider_id), | |
| 32 main_thread_loop_proxy_(base::MessageLoopProxy::current()), | |
| 33 thread_safe_sender_(ChildThread::current()->thread_safe_sender()) { | |
| 34 ServiceWorkerDispatcher* dispatcher = | |
| 35 ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance( | |
| 36 thread_safe_sender_); | |
| 37 DCHECK(dispatcher); | |
| 38 dispatcher->AddProviderContext(this); | |
| 39 } | |
| 40 | |
| 41 ServiceWorkerProviderContext::~ServiceWorkerProviderContext() { | |
| 42 DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread()); | |
| 43 if (ServiceWorkerDispatcher* dispatcher = | |
| 44 ServiceWorkerDispatcher::GetThreadSpecificInstance()) { | |
| 45 dispatcher->RemoveProviderContext(this); | |
| 46 } | |
| 47 } | |
| 48 | |
| 49 void ServiceWorkerProviderContext::AddProviderThreadAndGetInitializationInfo( | |
| 50 int thread_id, | |
| 51 scoped_ptr<ScopedServiceWorkerReference>* current) { | |
| 52 base::AutoLock lock(lock_); | |
| 53 DCHECK(!ContainsKey(provider_thread_ids_, thread_id)); | |
| 54 provider_thread_ids_.insert(thread_id); | |
| 55 if (current_) { | |
| 56 *current = ScopedServiceWorkerReference::Create( | |
| 57 current_->info(), thread_safe_sender_); | |
| 58 } | |
| 59 } | |
| 60 | |
| 61 void ServiceWorkerProviderContext::RemoveProviderThread(int thread_id) { | |
| 62 base::AutoLock lock(lock_); | |
| 63 provider_thread_ids_.erase(thread_id); | |
| 64 } | |
| 65 | |
| 66 void ServiceWorkerProviderContext::OnServiceWorkerStateChanged( | |
| 67 int thread_id, | |
| 68 int handle_id, | |
| 69 blink::WebServiceWorkerState state) { | |
| 70 // Currently .current is the only ServiceWorker associated to this provider. | |
| 71 DCHECK_EQ(current_->handle_id(), handle_id); | |
| 72 std::set<int> thread_ids; | |
| 73 { | |
| 74 base::AutoLock lock(lock_); | |
| 75 current_->set_state(state); | |
| 76 thread_ids = provider_thread_ids_; | |
| 77 } | |
| 78 ForwardMessageToProviderThreads( | |
| 79 ServiceWorkerMsg_ServiceWorkerStateChanged( | |
| 80 thread_id, handle_id, state), thread_ids); | |
| 81 } | |
| 82 | |
| 83 void ServiceWorkerProviderContext::OnSetCurrentServiceWorker( | |
| 84 int thread_id, | |
| 85 int provider_id, | |
| 86 const ServiceWorkerObjectInfo& info) { | |
| 87 DCHECK_EQ(provider_id_, provider_id); | |
| 88 std::set<int> thread_ids; | |
| 89 { | |
| 90 base::AutoLock lock(lock_); | |
| 91 current_ = ScopedServiceWorkerReference::Create( | |
| 92 info, thread_safe_sender_); | |
| 93 thread_ids = provider_thread_ids_; | |
| 94 } | |
| 95 ForwardMessageToProviderThreads( | |
| 96 ServiceWorkerMsg_SetCurrentServiceWorker( | |
| 97 thread_id, provider_id, info), thread_ids); | |
|
falken
2014/05/01 12:19:29
I'm trying to understand how this works. At first
kinuko
2014/05/02 10:00:56
This may not be very obvious, but:
1. ProviderCont
| |
| 98 } | |
| 99 | |
| 100 const ServiceWorkerObjectInfo& ServiceWorkerProviderContext::current() const { | |
| 101 base::AutoLock lock(lock_); | |
| 102 return current_->info(); | |
|
michaeln
2014/05/01 01:25:18
don't think we can return this ptr type to the str
kinuko
2014/05/02 10:00:56
Changed to return it as a value type.
| |
| 103 } | |
| 104 | |
| 105 void ServiceWorkerProviderContext::DestructOnMainThread() const { | |
| 106 if (!main_thread_loop_proxy_->RunsTasksOnCurrentThread() && | |
| 107 main_thread_loop_proxy_->DeleteSoon(FROM_HERE, this)) { | |
|
michaeln
2014/05/01 01:25:18
not sure if its possible for a background thread t
kinuko
2014/05/02 10:00:56
Hmm.. it might be better. Done.
| |
| 108 return; | |
| 109 } | |
| 110 delete this; | |
| 111 } | |
| 112 | |
| 113 void ServiceWorkerProviderContext::ForwardMessageToProviderThreads( | |
|
michaeln
2014/05/01 01:25:18
I see how messages are forwarded, but I don't see
kinuko
2014/05/02 10:00:56
WebSWProviderImpls are created on the main thread
| |
| 114 const IPC::Message& message, | |
| 115 const std::set<int>& thread_ids) { | |
| 116 for (std::set<int>::iterator it = thread_ids.begin(); | |
| 117 it != thread_ids.end(); | |
| 118 ++it) { | |
| 119 int thread_id = *it; | |
| 120 if (thread_id != WorkerTaskRunner::Instance()->CurrentWorkerId()) { | |
| 121 WorkerTaskRunner::Instance()->PostTask( | |
| 122 thread_id, | |
| 123 base::Bind(&ForwardMessage, | |
| 124 base::Passed(make_scoped_ptr(new IPC::Message(message))))); | |
| 125 } | |
| 126 } | |
| 127 } | |
| 128 | |
| 129 } // namespace content | |
| OLD | NEW |