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

Unified 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: addressed comments 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/service_worker/service_worker_version.cc
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index 6389d75d6eaea9aedb8df9777a3d5e2bd410cadd..8fe826d11c4a2608d0ee51e941517a007157e6de 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -13,10 +13,14 @@
namespace content {
+typedef ServiceWorkerVersion::StatusCallback StatusCallback;
+typedef ServiceWorkerVersion::MessageCallback MessageCallback;
+
namespace {
void RunSoon(const base::Closure& callback) {
- base::MessageLoop::current()->PostTask(FROM_HERE, callback);
+ if (!callback.is_null())
+ base::MessageLoop::current()->PostTask(FROM_HERE, callback);
}
template <typename CallbackArray, typename Arg>
@@ -26,6 +30,33 @@ void RunCallbacks(const CallbackArray& callbacks, const Arg& arg) {
(*i).Run(arg);
}
+// A callback adapter to start a |task| after StartWorker.
+void RunTaskAfterStartWorker(
+ base::WeakPtr<ServiceWorkerVersion> version,
+ const StatusCallback& error_callback,
+ const base::Closure& task,
+ ServiceWorkerStatusCode status) {
+ if (status != SERVICE_WORKER_OK) {
+ if (!error_callback.is_null())
+ error_callback.Run(status);
+ return;
+ }
+ if (version->status() != ServiceWorkerVersion::RUNNING) {
+ // We've tried to start the worker (and it has succeeded), but
+ // it looks it's not running yet.
+ NOTREACHED() << "The worker's not running after successful StartWorker";
+ if (!error_callback.is_null())
+ error_callback.Run(SERVICE_WORKER_ERROR_START_WORKER_FAILED);
+ return;
+ }
+ task.Run();
+}
+
+void RunEmptyMessageCallback(const MessageCallback& callback,
+ ServiceWorkerStatusCode status) {
+ callback.Run(status, IPC::Message());
+}
+
} // namespace
ServiceWorkerVersion::ServiceWorkerVersion(
@@ -34,7 +65,8 @@ ServiceWorkerVersion::ServiceWorkerVersion(
int64 version_id)
: version_id_(version_id),
is_shutdown_(false),
- registration_(registration) {
+ registration_(registration),
+ weak_factory_(this) {
if (worker_registry) {
embedded_worker_ = worker_registry->CreateWorker();
embedded_worker_->AddObserver(this);
@@ -93,12 +125,55 @@ void ServiceWorkerVersion::StopWorker(const StatusCallback& callback) {
stop_callbacks_.push_back(callback);
}
+void ServiceWorkerVersion::SendMessage(
+ const IPC::Message& message, const StatusCallback& callback) {
+ DCHECK(!is_shutdown_);
+ DCHECK(embedded_worker_);
+ if (status() != RUNNING) {
+ // Schedule calling this method after starting the worker.
+ StartWorker(base::Bind(&RunTaskAfterStartWorker,
+ weak_factory_.GetWeakPtr(), callback,
+ base::Bind(&self::SendMessage,
+ weak_factory_.GetWeakPtr(),
+ message, callback)));
+ return;
+ }
+
+ ServiceWorkerStatusCode status = embedded_worker_->SendMessage(-1, message);
+ RunSoon(base::Bind(callback, status));
+}
+
+void ServiceWorkerVersion::SendMessageAndRegisterCallback(
+ const IPC::Message& message, const MessageCallback& callback) {
+ DCHECK(!is_shutdown_);
+ DCHECK(embedded_worker_);
+ if (status() != RUNNING) {
+ // Schedule calling this method after starting the worker.
+ StartWorker(base::Bind(&RunTaskAfterStartWorker,
+ weak_factory_.GetWeakPtr(),
+ base::Bind(&RunEmptyMessageCallback, callback),
+ base::Bind(&self::SendMessageAndRegisterCallback,
+ weak_factory_.GetWeakPtr(),
+ message, callback)));
+ return;
+ }
+
+ int request_id = message_callbacks_.Add(new MessageCallback(callback));
+ ServiceWorkerStatusCode status =
+ embedded_worker_->SendMessage(request_id, message);
+ if (status != SERVICE_WORKER_OK) {
+ message_callbacks_.Remove(request_id);
+ RunSoon(base::Bind(callback, status, IPC::Message()));
+ return;
+ }
+}
+
bool ServiceWorkerVersion::DispatchFetchEvent(
const ServiceWorkerFetchRequest& request) {
if (status() != RUNNING)
return false;
return embedded_worker_->SendMessage(
- ServiceWorkerMsg_FetchEvent(request)) == SERVICE_WORKER_OK;
+ -1, ServiceWorkerMsg_FetchEvent(request)) == SERVICE_WORKER_OK;
jsbell 2014/02/04 23:29:03 Sorry for the late drive-by, but -1 is a magic num
}
void ServiceWorkerVersion::AddProcessToWorker(int process_id) {
@@ -123,14 +198,30 @@ void ServiceWorkerVersion::OnStopped() {
RunCallbacks(stop_callbacks_, SERVICE_WORKER_OK);
stop_callbacks_.clear();
- // If there're any callbacks that were waiting start let them know it's
- // failed.
+ // Let all start callbacks fail.
RunCallbacks(start_callbacks_, SERVICE_WORKER_ERROR_START_WORKER_FAILED);
start_callbacks_.clear();
+
+ // Let all message callbacks fail.
+ // TODO(kinuko): Consider if we want to add queue+resend mechanism here.
+ IDMap<MessageCallback, IDMapOwnPointer>::iterator iter(&message_callbacks_);
+ while (!iter.IsAtEnd()) {
+ iter.GetCurrentValue()->Run(SERVICE_WORKER_ERROR_ABORT, IPC::Message());
+ iter.Advance();
+ }
+ message_callbacks_.Clear();
}
-void ServiceWorkerVersion::OnMessageReceived(const IPC::Message& message) {
- NOTREACHED();
+void ServiceWorkerVersion::OnMessageReceived(
+ int request_id, const IPC::Message& message) {
+ MessageCallback* callback = message_callbacks_.Lookup(request_id);
+ if (callback) {
+ callback->Run(SERVICE_WORKER_OK, message);
+ message_callbacks_.Remove(request_id);
+ return;
+ }
+ NOTREACHED() << "Got unexpected message: " << request_id
+ << " " << message.type();
}
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698