Commit ce190ab7 authored by dimich@google.com's avatar dimich@google.com

Fix the GC of workers. When Worker object is GC'ed in the renderer, we need to...

Fix the GC of workers. When Worker object is GC'ed in the renderer, we need to terminate the worker process.
BUG=15647, 15759
TEST=new ui_test is part of this CL
Review URL: http://codereview.chromium.org/151125

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20034 0039d316-1c4b-4281-b951-d872f2087c98
parent d1259e8b
...@@ -25,15 +25,26 @@ WebWorkerProxy::WebWorkerProxy( ...@@ -25,15 +25,26 @@ WebWorkerProxy::WebWorkerProxy(
} }
WebWorkerProxy::~WebWorkerProxy() { WebWorkerProxy::~WebWorkerProxy() {
if (queued_messages_.empty()) Disconnect();
return;
for (size_t i = 0; i < queued_messages_.size(); ++i) for (size_t i = 0; i < queued_messages_.size(); ++i)
delete queued_messages_[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. // 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_)); child_thread_->Send(new ViewHostMsg_CancelCreateDedicatedWorker(route_id_));
route_id_ = MSG_ROUTING_NONE;
} }
void WebWorkerProxy::startWorkerContext( void WebWorkerProxy::startWorkerContext(
...@@ -57,8 +68,7 @@ void WebWorkerProxy::startWorkerContext( ...@@ -57,8 +68,7 @@ void WebWorkerProxy::startWorkerContext(
void WebWorkerProxy::terminateWorkerContext() { void WebWorkerProxy::terminateWorkerContext() {
if (route_id_ != MSG_ROUTING_NONE) { if (route_id_ != MSG_ROUTING_NONE) {
Send(new WorkerMsg_TerminateWorkerContext(route_id_)); Send(new WorkerMsg_TerminateWorkerContext(route_id_));
child_thread_->RemoveRoute(route_id_); Disconnect();
route_id_ = MSG_ROUTING_NONE;
} }
} }
......
...@@ -43,6 +43,7 @@ class WebWorkerProxy : public WebKit::WebWorker, ...@@ -43,6 +43,7 @@ class WebWorkerProxy : public WebKit::WebWorker,
bool Send(IPC::Message* message); bool Send(IPC::Message* message);
void OnDedicatedWorkerCreated(); void OnDedicatedWorkerCreated();
void Disconnect();
// The routing id used to reach WebWorkerClientProxy in the worker process. // The routing id used to reach WebWorkerClientProxy in the worker process.
int route_id_; int route_id_;
......
...@@ -119,7 +119,8 @@ void InitializeWebKitStaticValues() { ...@@ -119,7 +119,8 @@ void InitializeWebKitStaticValues() {
WebWorkerImpl::WebWorkerImpl(WebWorkerClient* client) WebWorkerImpl::WebWorkerImpl(WebWorkerClient* client)
: client_(client), : client_(client),
web_view_(NULL) { web_view_(NULL),
asked_to_terminate_(false) {
InitializeWebKitStaticValues(); InitializeWebKitStaticValues();
} }
...@@ -193,6 +194,10 @@ void WebWorkerImpl::startWorkerContext(const WebURL& script_url, ...@@ -193,6 +194,10 @@ void WebWorkerImpl::startWorkerContext(const WebURL& script_url,
} }
void WebWorkerImpl::terminateWorkerContext() { void WebWorkerImpl::terminateWorkerContext() {
if (asked_to_terminate_)
return;
asked_to_terminate_ = true;
if (worker_thread_) if (worker_thread_)
worker_thread_->stop(); worker_thread_->stop();
} }
...@@ -207,6 +212,11 @@ void WebWorkerImpl::postMessageToWorkerContext(const WebString& message) { ...@@ -207,6 +212,11 @@ void WebWorkerImpl::postMessageToWorkerContext(const WebString& message) {
} }
void WebWorkerImpl::workerObjectDestroyed() { 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( void WebWorkerImpl::DispatchTaskToMainThread(
......
...@@ -125,6 +125,7 @@ class WebWorkerImpl: public WebCore::WorkerObjectProxy, ...@@ -125,6 +125,7 @@ class WebWorkerImpl: public WebCore::WorkerObjectProxy,
// 'shadow page' - created to proxy loading requests from the worker. // 'shadow page' - created to proxy loading requests from the worker.
WTF::RefPtr<WebCore::ScriptExecutionContext> loading_document_; WTF::RefPtr<WebCore::ScriptExecutionContext> loading_document_;
WebView* web_view_; WebView* web_view_;
bool asked_to_terminate_;
WTF::RefPtr<WebCore::WorkerThread> worker_thread_; WTF::RefPtr<WebCore::WorkerThread> worker_thread_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment