summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/renderer/webworker_proxy.cc20
-rw-r--r--chrome/renderer/webworker_proxy.h1
-rw-r--r--webkit/glue/webworker_impl.cc12
-rw-r--r--webkit/glue/webworker_impl.h1
4 files changed, 28 insertions, 6 deletions
diff --git a/chrome/renderer/webworker_proxy.cc b/chrome/renderer/webworker_proxy.cc
index 6cec8cc..b013aa9 100644
--- a/chrome/renderer/webworker_proxy.cc
+++ b/chrome/renderer/webworker_proxy.cc
@@ -25,15 +25,26 @@ WebWorkerProxy::WebWorkerProxy(
}
WebWorkerProxy::~WebWorkerProxy() {
- if (queued_messages_.empty())
- return;
+ Disconnect();
for (size_t i = 0; i < queued_messages_.size(); ++i)
delete queued_messages_[i];
+}
+
+void WebWorkerProxy::Disconnect() {
+ if (route_id_ == MSG_ROUTING_NONE)
+ return;
+
+ // So the messages from WorkerContext (like WorkerContextDestroyed) do not
+ // come after nobody is listening. Since Worker and WorkerContext can
+ // terminate independently, already sent messages may still be in the pipe.
+ child_thread_->RemoveRoute(route_id_);
// Tell the browser to not start our queued worker.
- if (route_id_ != MSG_ROUTING_NONE)
+ if (!queued_messages_.empty())
child_thread_->Send(new ViewHostMsg_CancelCreateDedicatedWorker(route_id_));
+
+ route_id_ = MSG_ROUTING_NONE;
}
void WebWorkerProxy::startWorkerContext(
@@ -57,8 +68,7 @@ void WebWorkerProxy::startWorkerContext(
void WebWorkerProxy::terminateWorkerContext() {
if (route_id_ != MSG_ROUTING_NONE) {
Send(new WorkerMsg_TerminateWorkerContext(route_id_));
- child_thread_->RemoveRoute(route_id_);
- route_id_ = MSG_ROUTING_NONE;
+ Disconnect();
}
}
diff --git a/chrome/renderer/webworker_proxy.h b/chrome/renderer/webworker_proxy.h
index 7dacf07..dac97aa 100644
--- a/chrome/renderer/webworker_proxy.h
+++ b/chrome/renderer/webworker_proxy.h
@@ -43,6 +43,7 @@ class WebWorkerProxy : public WebKit::WebWorker,
bool Send(IPC::Message* message);
void OnDedicatedWorkerCreated();
+ void Disconnect();
// The routing id used to reach WebWorkerClientProxy in the worker process.
int route_id_;
diff --git a/webkit/glue/webworker_impl.cc b/webkit/glue/webworker_impl.cc
index 65131d5..625f0d8 100644
--- a/webkit/glue/webworker_impl.cc
+++ b/webkit/glue/webworker_impl.cc
@@ -119,7 +119,8 @@ void InitializeWebKitStaticValues() {
WebWorkerImpl::WebWorkerImpl(WebWorkerClient* client)
: client_(client),
- web_view_(NULL) {
+ web_view_(NULL),
+ asked_to_terminate_(false) {
InitializeWebKitStaticValues();
}
@@ -193,6 +194,10 @@ void WebWorkerImpl::startWorkerContext(const WebURL& script_url,
}
void WebWorkerImpl::terminateWorkerContext() {
+ if (asked_to_terminate_)
+ return;
+ asked_to_terminate_ = true;
+
if (worker_thread_)
worker_thread_->stop();
}
@@ -207,6 +212,11 @@ void WebWorkerImpl::postMessageToWorkerContext(const WebString& message) {
}
void WebWorkerImpl::workerObjectDestroyed() {
+ // Worker object in the renderer was destroyed, perhaps a result of GC.
+ // For us, it's a signal to start terminating the WorkerContext too.
+ // TODO(dimich): when 'kill a worker' html5 spec algorithm is implemented, it
+ // should be used here instead of 'terminate a worker'.
+ terminateWorkerContext();
}
void WebWorkerImpl::DispatchTaskToMainThread(
diff --git a/webkit/glue/webworker_impl.h b/webkit/glue/webworker_impl.h
index 6f083b6..f7daf42 100644
--- a/webkit/glue/webworker_impl.h
+++ b/webkit/glue/webworker_impl.h
@@ -125,6 +125,7 @@ class WebWorkerImpl: public WebCore::WorkerObjectProxy,
// 'shadow page' - created to proxy loading requests from the worker.
WTF::RefPtr<WebCore::ScriptExecutionContext> loading_document_;
WebView* web_view_;
+ bool asked_to_terminate_;
WTF::RefPtr<WebCore::WorkerThread> worker_thread_;