WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
25902
Need to implement WorkerContext.close()
https://bugs.webkit.org/show_bug.cgi?id=25902
Summary
Need to implement WorkerContext.close()
Andrew Wilson
Reported
2009-05-20 18:33:01 PDT
There's still some argument about whether we need to support close events on Worker and WorkerContext arguments, since they expose information about garbage collection. However, we should still support an explicit WorkerContext.close() API to allow workers to shut themselves down.
Attachments
Implementation of WorkerContext.close() + layout test
(5.75 KB, patch)
2009-05-22 13:09 PDT
,
Andrew Wilson
ap
: review-
Details
Formatted Diff
Diff
proposed patch with requested changes
(14.05 KB, patch)
2009-05-28 14:50 PDT
,
Andrew Wilson
darin
: review+
Details
Formatted Diff
Diff
Show Obsolete
(1)
View All
Add attachment
proposed patch, testcase, etc.
Andrew Wilson
Comment 1
2009-05-22 13:09:14 PDT
Created
attachment 30590
[details]
Implementation of WorkerContext.close() + layout test
Eric Seidel (no email)
Comment 2
2009-05-22 20:08:48 PDT
Comment on
attachment 30590
[details]
Implementation of WorkerContext.close() + layout test Looks good to me. I think the test would be slightly more clear if you called worker.postMessge('ping') *before* calling close, to show that the ping worked before the close. This looks fine though. Marking r+, someone else will have to land this though because I'm about to get on a plane.
Alexey Proskuryakov
Comment 3
2009-05-22 23:37:04 PDT
Comment on
attachment 30590
[details]
Implementation of WorkerContext.close() + layout test Looks like this has a race condition in the following situation: 1) Worker thread decides to close itself, calling stop(), and subsequently destroying WorkerContext object, notifying the proxy, and exiting the thread itself. 2) At the same time, a message is sent from the main thread to the worker thread. Since it takes time to deliver a workerContextDestroyed notification, this message will be added to deleted WorkerContext's queue. I think that the right way to implement close() is send a custom message to the proxy, asking it to terminate the context in response, and to wait for this in some "death row" state that prevents any other communication with the proxy. Please add a test for this situation (if at all possible, one that would crash with this patch). Please also add a test for a situation where the worker decides to close itself from an XHR onreadystatechange callback, not in response to a message from the main thread. It would be nice to verify that this doesn't introduce leaks.
Andrew Wilson
Comment 4
2009-05-26 11:01:52 PDT
I'll add the requested tests. I'm not certain that there's a race condition - the reason is that the event queue for the worker (WorkerRunLoop) is associated with the WorkerThread, not with the WorkerContext. So you can still safely invoke m_workerThread->runLoop().postTask() from postMessageToWorkerContext() even after the WorkerContext itself has gone away. There also should be no leak, as once the WorkerThread is freed, the WorkerRunLoop and any events left on the queue will also be freed (note that the MessageQueue may have some items left on it anyway, since MessageQueue::kill doesn't empty the queue).
Alexey Proskuryakov
Comment 5
2009-05-26 13:09:38 PDT
Indeed, I was wrong about the race condition. Does this implementation of close() do what the spec says? Omitting MessagePort related steps, it is: 1) Queue a task to fire a simple event called close at the WorkerGlobalScope object. 2) Set the worker's WorkerGlobalScope object's closing flag to true (which means that new tasks do not get added to event loop, but those already in the loop will be processed).
Andrew Wilson
Comment 6
2009-05-26 13:47:19 PDT
In the first case, no, we don't fire off a close event - the reason why is because I'm still working to convince IanH that we should remove the close event from WorkerGlobalScope (the reason is that we don't want to expose the internal behavior of garbage collection via the close event, and generating a close event *only* in response to an explicit close() invocation seems of dubious utility). Thanks for pointing out the spec language around proper handling of events that are already in the queue - I missed that behavior since it's described in a different part of the spec. It seems like the best way to do that is to have close send an event via the queue which itself calls WorkerThread::stop(). Any timer/XHR events that come in after that event will get dropped. Do you see any problems with that approach?
Alexey Proskuryakov
Comment 7
2009-05-26 23:59:40 PDT
Sounds good to me.
Andrew Wilson
Comment 8
2009-05-27 11:13:04 PDT
Following up with this - turns out that just queueing up a task to invoke close() won't work. The reason is that WorkerRunLoop does not guarantee ordering in the dispatch of pending events (MessageQueue.waitForMessageFilteredWithTimeout() will only return MessageQueueTimeout if the queue is empty, meaning that timer events are only fired if/when the queue is empty. I'm discussing with ianh whether we should change close() to just drop pending events (if a worker wants different functionality, it could just use setTimeout(close, 0);
Andrew Wilson
Comment 9
2009-05-28 14:50:59 PDT
Created
attachment 30752
[details]
proposed patch with requested changes Updated patch with requested tests. The latest spec for WorkerContext.close() discards all pending events, so I've updated the code and tests to reflect this. Note that there's a minor issue with pending XMLHttpRequest events - those aren't always delivered via the event queue, so if you call WorkerContext.close() from an XHR callback you can still get another event callback invoked before the thread exits. I'll log a separate bug for this.
Darin Adler
Comment 10
2009-06-01 00:35:26 PDT
Comment on
attachment 30752
[details]
proposed patch with requested changes I normally prefer early return to nesting work inside if statements. So in close and postMessage we'd put: if (m_closing) return; At the start of the function, and then go on with the work of the function. I much prefer change logs with per-function comments. Given Alexey's previous comments this looks good. r=me
Adam Barth
Comment 11
2009-06-01 01:17:14 PDT
Will land.
Adam Barth
Comment 12
2009-06-01 02:00:48 PDT
Sending LayoutTests/ChangeLog Adding LayoutTests/fast/workers/resources/worker-close.js Sending LayoutTests/fast/workers/resources/worker-common.js Adding LayoutTests/fast/workers/worker-close-expected.txt Adding LayoutTests/fast/workers/worker-close.html Adding LayoutTests/http/tests/xmlhttprequest/workers/close-expected.txt Adding LayoutTests/http/tests/xmlhttprequest/workers/close.html Adding LayoutTests/http/tests/xmlhttprequest/workers/resources/close.js Sending WebCore/ChangeLog Sending WebCore/workers/WorkerContext.cpp Sending WebCore/workers/WorkerContext.h Sending WebCore/workers/WorkerContext.idl Sending WebCore/workers/WorkerMessagingProxy.cpp Transmitting file data ............. Committed revision 44319.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug