summaryrefslogtreecommitdiffstats
path: root/chrome/renderer
diff options
context:
space:
mode:
authoratwilson@chromium.org <atwilson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-17 22:00:51 +0000
committeratwilson@chromium.org <atwilson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-17 22:00:51 +0000
commit6de0bcf0025517c4f31eafce162d90588c609103 (patch)
tree8ae27ceda2696e65a7b6d7b2d6a5474811914d88 /chrome/renderer
parent87ef23a2a8a693c9452ddf5c65d47c9fd62e032f (diff)
downloadchromium_src-6de0bcf0025517c4f31eafce162d90588c609103.zip
chromium_src-6de0bcf0025517c4f31eafce162d90588c609103.tar.gz
chromium_src-6de0bcf0025517c4f31eafce162d90588c609103.tar.bz2
Fixes a race condition when a shared worker exits while one parent is loading
it. Changed the shared worker startup code to assign a route ID at the time that we initially lookup the worker, and pass that same route ID in when we later try to create the worker, to gracefully handle this race condition. BUG=29243 TEST=existing tests suffice (can't reproduce race condition in tests) Review URL: http://codereview.chromium.org/600103 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39274 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r--chrome/renderer/render_view.cc11
-rw-r--r--chrome/renderer/websharedworker_proxy.cc10
-rw-r--r--chrome/renderer/websharedworker_proxy.h5
-rw-r--r--chrome/renderer/webworker_base.cc4
-rw-r--r--chrome/renderer/webworker_base.h3
-rw-r--r--chrome/renderer/webworker_proxy.cc3
6 files changed, 30 insertions, 6 deletions
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index c387004..ac6af64 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -1987,14 +1987,23 @@ WebSharedWorker* RenderView::createSharedWorker(
unsigned long long document_id) {
int route_id = MSG_ROUTING_NONE;
+ bool exists = false;
bool url_mismatch = false;
+ ViewHostMsg_CreateWorker_Params params;
+ params.url = url;
+ params.is_shared = true;
+ params.name = name;
+ params.document_id = document_id;
+ params.render_view_route_id = routing_id_;
+ params.route_id = MSG_ROUTING_NONE;
Send(new ViewHostMsg_LookupSharedWorker(
- url, name, document_id, routing_id_, &route_id, &url_mismatch));
+ params, &exists, &route_id, &url_mismatch));
if (url_mismatch) {
return NULL;
} else {
return new WebSharedWorkerProxy(RenderThread::current(),
document_id,
+ exists,
route_id,
routing_id_);
}
diff --git a/chrome/renderer/websharedworker_proxy.cc b/chrome/renderer/websharedworker_proxy.cc
index c6741c1..afb668f 100644
--- a/chrome/renderer/websharedworker_proxy.cc
+++ b/chrome/renderer/websharedworker_proxy.cc
@@ -11,9 +11,14 @@
WebSharedWorkerProxy::WebSharedWorkerProxy(ChildThread* child_thread,
unsigned long long document_id,
+ bool exists,
int route_id,
int render_view_route_id)
- : WebWorkerBase(child_thread, document_id, route_id, render_view_route_id),
+ : WebWorkerBase(child_thread,
+ document_id,
+ exists ? route_id : MSG_ROUTING_NONE,
+ render_view_route_id),
+ pending_route_id_(route_id),
connect_listener_(NULL) {
}
@@ -27,7 +32,8 @@ void WebSharedWorkerProxy::startWorkerContext(
const WebKit::WebString& user_agent,
const WebKit::WebString& source_code) {
DCHECK(!isStarted());
- CreateWorkerContext(script_url, true, name, user_agent, source_code);
+ CreateWorkerContext(script_url, true, name, user_agent, source_code,
+ pending_route_id_);
}
void WebSharedWorkerProxy::terminateWorkerContext() {
diff --git a/chrome/renderer/websharedworker_proxy.h b/chrome/renderer/websharedworker_proxy.h
index 4a93ff6..be88871 100644
--- a/chrome/renderer/websharedworker_proxy.h
+++ b/chrome/renderer/websharedworker_proxy.h
@@ -23,6 +23,7 @@ class WebSharedWorkerProxy : public WebKit::WebSharedWorker,
// If the worker not loaded yet, route_id == MSG_ROUTING_NONE
WebSharedWorkerProxy(ChildThread* child_thread,
unsigned long long document_id,
+ bool exists,
int route_id,
int render_view_route_id);
@@ -43,6 +44,10 @@ class WebSharedWorkerProxy : public WebKit::WebSharedWorker,
private:
void OnWorkerCreated();
+ // The id for the placeholder worker instance we've stored on the
+ // browser process (we need to pass this same route id back in when creating
+ // the worker).
+ int pending_route_id_;
ConnectListener* connect_listener_;
DISALLOW_COPY_AND_ASSIGN(WebSharedWorkerProxy);
diff --git a/chrome/renderer/webworker_base.cc b/chrome/renderer/webworker_base.cc
index e78ef64..2bc10b5 100644
--- a/chrome/renderer/webworker_base.cc
+++ b/chrome/renderer/webworker_base.cc
@@ -54,7 +54,8 @@ void WebWorkerBase::CreateWorkerContext(const GURL& script_url,
bool is_shared,
const string16& name,
const string16& user_agent,
- const string16& source_code) {
+ const string16& source_code,
+ int pending_route_id) {
DCHECK(route_id_ == MSG_ROUTING_NONE);
ViewHostMsg_CreateWorker_Params params;
params.url = script_url;
@@ -62,6 +63,7 @@ void WebWorkerBase::CreateWorkerContext(const GURL& script_url,
params.name = name;
params.document_id = document_id_;
params.render_view_route_id = render_view_route_id_;
+ params.route_id = pending_route_id;
IPC::Message* create_message = new ViewHostMsg_CreateWorker(
params, &route_id_);
child_thread_->Send(create_message);
diff --git a/chrome/renderer/webworker_base.h b/chrome/renderer/webworker_base.h
index 6c031c8..b6b3da8 100644
--- a/chrome/renderer/webworker_base.h
+++ b/chrome/renderer/webworker_base.h
@@ -31,7 +31,8 @@ class WebWorkerBase : public IPC::Channel::Listener {
bool is_shared,
const string16& name,
const string16& user_agent,
- const string16& source_code);
+ const string16& source_code,
+ int pending_route_id);
// Returns true if the worker is running (can send messages to it).
bool IsStarted();
diff --git a/chrome/renderer/webworker_proxy.cc b/chrome/renderer/webworker_proxy.cc
index 553a3ac..e64abf6 100644
--- a/chrome/renderer/webworker_proxy.cc
+++ b/chrome/renderer/webworker_proxy.cc
@@ -46,7 +46,8 @@ void WebWorkerProxy::startWorkerContext(
const WebURL& script_url,
const WebString& user_agent,
const WebString& source_code) {
- CreateWorkerContext(script_url, false, string16(), user_agent, source_code);
+ CreateWorkerContext(script_url, false, string16(), user_agent, source_code,
+ MSG_ROUTING_NONE);
}
void WebWorkerProxy::terminateWorkerContext() {