Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: content/browser/service_worker/service_worker_version.cc

Issue 139923005: Implement ServiceWorkerVersion::SendMessage() (for dispatching events etc) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/service_worker/service_worker_version.h" 5 #include "content/browser/service_worker/service_worker_version.h"
6 6
7 #include "base/stl_util.h" 7 #include "base/stl_util.h"
8 #include "content/browser/service_worker/embedded_worker_instance.h" 8 #include "content/browser/service_worker/embedded_worker_instance.h"
9 #include "content/browser/service_worker/embedded_worker_registry.h" 9 #include "content/browser/service_worker/embedded_worker_registry.h"
10 #include "content/browser/service_worker/service_worker_context_core.h" 10 #include "content/browser/service_worker/service_worker_context_core.h"
11 #include "content/browser/service_worker/service_worker_registration.h" 11 #include "content/browser/service_worker/service_worker_registration.h"
12 #include "content/common/service_worker/service_worker_messages.h" 12 #include "content/common/service_worker/service_worker_messages.h"
13 13
14 namespace content { 14 namespace content {
15 15
16 typedef ServiceWorkerVersion::StatusCallback StatusCallback;
17 typedef ServiceWorkerVersion::MessageCallback MessageCallback;
18
16 namespace { 19 namespace {
17 20
18 void RunSoon(const base::Closure& callback) { 21 void RunSoon(const base::Closure& callback) {
19 base::MessageLoop::current()->PostTask(FROM_HERE, callback); 22 if (!callback.is_null())
23 base::MessageLoop::current()->PostTask(FROM_HERE, callback);
20 } 24 }
21 25
22 template <typename CallbackArray, typename Arg> 26 template <typename CallbackArray, typename Arg>
23 void RunCallbacks(const CallbackArray& callbacks, const Arg& arg) { 27 void RunCallbacks(const CallbackArray& callbacks, const Arg& arg) {
24 for (typename CallbackArray::const_iterator i = callbacks.begin(); 28 for (typename CallbackArray::const_iterator i = callbacks.begin();
25 i != callbacks.end(); ++i) 29 i != callbacks.end(); ++i)
26 (*i).Run(arg); 30 (*i).Run(arg);
27 } 31 }
28 32
33 // A callback adapter to start a |task| after StartWorker.
34 void RunTaskAfterStartWorker(
35 base::WeakPtr<ServiceWorkerVersion> version,
36 const StatusCallback& error_callback,
37 const base::Closure& task,
38 ServiceWorkerStatusCode status) {
39 if (status != SERVICE_WORKER_OK) {
40 if (!error_callback.is_null())
41 error_callback.Run(status);
42 return;
43 }
44 if (version->status() != ServiceWorkerVersion::RUNNING) {
45 // We've tried to start the worker (and it has succeeded), but
46 // it looks it's not running yet.
47 NOTREACHED() << "The worker's not running after successful StartWorker";
48 if (!error_callback.is_null())
49 error_callback.Run(SERVICE_WORKER_ERROR_START_WORKER_FAILED);
50 return;
51 }
52 task.Run();
53 }
54
55 void RunEmptyMessageCallback(const MessageCallback& callback,
56 ServiceWorkerStatusCode status) {
57 callback.Run(status, IPC::Message());
58 }
59
29 } // namespace 60 } // namespace
30 61
31 ServiceWorkerVersion::ServiceWorkerVersion( 62 ServiceWorkerVersion::ServiceWorkerVersion(
32 ServiceWorkerRegistration* registration, 63 ServiceWorkerRegistration* registration,
33 EmbeddedWorkerRegistry* worker_registry, 64 EmbeddedWorkerRegistry* worker_registry,
34 int64 version_id) 65 int64 version_id)
35 : version_id_(version_id), 66 : version_id_(version_id),
36 is_shutdown_(false), 67 is_shutdown_(false),
37 registration_(registration) { 68 registration_(registration),
69 weak_factory_(this) {
38 if (worker_registry) { 70 if (worker_registry) {
39 embedded_worker_ = worker_registry->CreateWorker(); 71 embedded_worker_ = worker_registry->CreateWorker();
40 embedded_worker_->AddObserver(this); 72 embedded_worker_->AddObserver(this);
41 } 73 }
42 } 74 }
43 75
44 ServiceWorkerVersion::~ServiceWorkerVersion() { DCHECK(is_shutdown_); } 76 ServiceWorkerVersion::~ServiceWorkerVersion() { DCHECK(is_shutdown_); }
45 77
46 void ServiceWorkerVersion::Shutdown() { 78 void ServiceWorkerVersion::Shutdown() {
47 is_shutdown_ = true; 79 is_shutdown_ = true;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 if (stop_callbacks_.empty()) { 118 if (stop_callbacks_.empty()) {
87 ServiceWorkerStatusCode status = embedded_worker_->Stop(); 119 ServiceWorkerStatusCode status = embedded_worker_->Stop();
88 if (status != SERVICE_WORKER_OK) { 120 if (status != SERVICE_WORKER_OK) {
89 RunSoon(base::Bind(callback, status)); 121 RunSoon(base::Bind(callback, status));
90 return; 122 return;
91 } 123 }
92 } 124 }
93 stop_callbacks_.push_back(callback); 125 stop_callbacks_.push_back(callback);
94 } 126 }
95 127
128 void ServiceWorkerVersion::SendMessage(
129 const IPC::Message& message, const StatusCallback& callback) {
130 DCHECK(!is_shutdown_);
131 DCHECK(embedded_worker_);
132 if (status() != RUNNING) {
133 // Schedule calling this method after starting the worker.
134 StartWorker(base::Bind(&RunTaskAfterStartWorker,
135 weak_factory_.GetWeakPtr(), callback,
136 base::Bind(&self::SendMessage,
137 weak_factory_.GetWeakPtr(),
138 message, callback)));
139 return;
140 }
141
142 ServiceWorkerStatusCode status = embedded_worker_->SendMessage(-1, message);
143 RunSoon(base::Bind(callback, status));
144 }
145
146 void ServiceWorkerVersion::SendMessageAndRegisterCallback(
147 const IPC::Message& message, const MessageCallback& callback) {
148 DCHECK(!is_shutdown_);
149 DCHECK(embedded_worker_);
150 if (status() != RUNNING) {
151 // Schedule calling this method after starting the worker.
152 StartWorker(base::Bind(&RunTaskAfterStartWorker,
153 weak_factory_.GetWeakPtr(),
154 base::Bind(&RunEmptyMessageCallback, callback),
155 base::Bind(&self::SendMessageAndRegisterCallback,
156 weak_factory_.GetWeakPtr(),
157 message, callback)));
158 return;
159 }
160
161 int request_id = message_callbacks_.Add(new MessageCallback(callback));
162 ServiceWorkerStatusCode status =
163 embedded_worker_->SendMessage(request_id, message);
164 if (status != SERVICE_WORKER_OK) {
165 message_callbacks_.Remove(request_id);
166 RunSoon(base::Bind(callback, status, IPC::Message()));
167 return;
168 }
169 }
170
96 bool ServiceWorkerVersion::DispatchFetchEvent( 171 bool ServiceWorkerVersion::DispatchFetchEvent(
97 const ServiceWorkerFetchRequest& request) { 172 const ServiceWorkerFetchRequest& request) {
98 if (status() != RUNNING) 173 if (status() != RUNNING)
99 return false; 174 return false;
100 return embedded_worker_->SendMessage( 175 return embedded_worker_->SendMessage(
101 ServiceWorkerMsg_FetchEvent(request)) == SERVICE_WORKER_OK; 176 -1, ServiceWorkerMsg_FetchEvent(request)) == SERVICE_WORKER_OK;
102 } 177 }
103 178
104 void ServiceWorkerVersion::AddProcessToWorker(int process_id) { 179 void ServiceWorkerVersion::AddProcessToWorker(int process_id) {
105 DCHECK(!is_shutdown_); 180 DCHECK(!is_shutdown_);
106 embedded_worker_->AddProcessReference(process_id); 181 embedded_worker_->AddProcessReference(process_id);
107 } 182 }
108 183
109 void ServiceWorkerVersion::RemoveProcessToWorker(int process_id) { 184 void ServiceWorkerVersion::RemoveProcessToWorker(int process_id) {
110 embedded_worker_->ReleaseProcessReference(process_id); 185 embedded_worker_->ReleaseProcessReference(process_id);
111 } 186 }
112 187
113 void ServiceWorkerVersion::OnStarted() { 188 void ServiceWorkerVersion::OnStarted() {
114 DCHECK_EQ(RUNNING, status()); 189 DCHECK_EQ(RUNNING, status());
115 // Fire all start callbacks. 190 // Fire all start callbacks.
116 RunCallbacks(start_callbacks_, SERVICE_WORKER_OK); 191 RunCallbacks(start_callbacks_, SERVICE_WORKER_OK);
117 start_callbacks_.clear(); 192 start_callbacks_.clear();
118 } 193 }
119 194
120 void ServiceWorkerVersion::OnStopped() { 195 void ServiceWorkerVersion::OnStopped() {
121 DCHECK_EQ(STOPPED, status()); 196 DCHECK_EQ(STOPPED, status());
122 // Fire all stop callbacks. 197 // Fire all stop callbacks.
123 RunCallbacks(stop_callbacks_, SERVICE_WORKER_OK); 198 RunCallbacks(stop_callbacks_, SERVICE_WORKER_OK);
124 stop_callbacks_.clear(); 199 stop_callbacks_.clear();
125 200
126 // If there're any callbacks that were waiting start let them know it's 201 // Let all start callbacks fail.
127 // failed.
128 RunCallbacks(start_callbacks_, SERVICE_WORKER_ERROR_START_WORKER_FAILED); 202 RunCallbacks(start_callbacks_, SERVICE_WORKER_ERROR_START_WORKER_FAILED);
129 start_callbacks_.clear(); 203 start_callbacks_.clear();
204
205 // Let all message callbacks fail.
alecflett 2014/02/04 20:53:24 lets add a TODO that indicates that in the future
kinuko 2014/02/04 22:50:24 It totally makes sense to resend install on anothe
206 IDMap<MessageCallback, IDMapOwnPointer>::iterator iter(&message_callbacks_);
207 while (!iter.IsAtEnd()) {
208 iter.GetCurrentValue()->Run(SERVICE_WORKER_ERROR_ABORT, IPC::Message());
209 iter.Advance();
210 }
211 message_callbacks_.Clear();
130 } 212 }
131 213
132 void ServiceWorkerVersion::OnMessageReceived(const IPC::Message& message) { 214 void ServiceWorkerVersion::OnMessageReceived(
133 NOTREACHED(); 215 int request_id, const IPC::Message& message) {
216 MessageCallback* callback = message_callbacks_.Lookup(request_id);
217 if (callback) {
218 callback->Run(SERVICE_WORKER_OK, message);
219 message_callbacks_.Remove(request_id);
alecflett 2014/02/04 20:53:24 This is going to be a little tricky - it's going t
kinuko 2014/02/04 22:17:12 I'm planning to wait ('join') all these promises i
220 return;
221 }
222 NOTREACHED() << "Got unexpected message: " << request_id
223 << " " << message.type();
134 } 224 }
135 225
136 } // namespace content 226 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698