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 |