diff options
-rw-r--r-- | chrome/renderer/webworker_proxy.cc | 20 | ||||
-rw-r--r-- | chrome/renderer/webworker_proxy.h | 1 | ||||
-rw-r--r-- | webkit/glue/webworker_impl.cc | 12 | ||||
-rw-r--r-- | webkit/glue/webworker_impl.h | 1 |
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_; |