[html5] Web Workers: Race-Condition setting onmessage handler?
Tobias Sauerwein
tobias.sauerwein at camptocamp.com
Tue Aug 3 04:21:44 PDT 2010
On Mon, Aug 2, 2010 at 7:09 PM, Drew Wilson <atwilson at chromium.org> wrote:
> (sending from the correct address this time)
>
> On Mon, Aug 2, 2010 at 7:57 AM, Jeremy Orlow <jorlow at google.com> wrote:
>
>>
>>
>> ---------- Forwarded message ----------
>> From: Tobias Sauerwein <tobias.sauerwein at camptocamp.com>
>> Date: Tue, Jul 27, 2010 at 8:46 AM
>> Subject: [html5] Web Workers: Race-Condition setting onmessage handler?
>> To: help at lists.whatwg.org
>>
>>
>> Hi!
>>
>> I am wondering what prevents a web worker from running into
>> race-conditions when setting the onmessage handlers. I am worried about that
>> a web worker posts a message before the main script has set up the onmessage
>> handler, or the other way around, that the web worker posts a message before
>> the main script has set up its onmessage handler.
>>
>> I know that there is a message queue [1], but you can easily make up an
>> example where a message is not enqueued:
>>
>> Main Script:
>>
>> var worker = new Worker("webworker.js");
>>> worker.onmessage = function(event) {
>>> console.log('onmessage ' + event.data)
>>> };
>>> worker.postMessage("start");
>>>
>>
>>
>> 'webworker.js':
>>
>> setTimeout(
>>> function() {
>>> onmessage = function(event) {
>>> postMessage("message received");
>>> };
>>> postMessage("done");
>>> }, 1000);
>>>
>>
>>
>> The output is (in Chromium 6.0.475.0 and Firefox 4.01b, Opera 10.70 also
>> outputs "onmessage message received"):
>>
>> onmessage done
>>>
>>
>> So the "onmessage" handler of the web worker is never called.
>>
>>
>> Is this the behavior the specification requests, or is it a bug in
>> Chrome/Chromium and Firefox?
>>
>> Tobias
>>
>>
>>
>> [1]:
>> http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#port-message-queue
>>
>> _______________________________________________
>> Help mailing list
>> Help at lists.whatwg.org
>> http://lists.whatwg.org/listinfo.cgi/help-whatwg.org
>>
>>
>> This is the correct behavior. If there is no onmessage event at the time
> that an event arrives at the worker's event loop, it will be dropped on the
> floor. The reason this happens is steps 7/8 in section 4.5 of the worker
> spec:
>
> 7. Jump to the script's *initial code entry-point*, and let that run until
> it either returns, fails to catch an exception, or gets prematurely aborted
> by the "kill a worker<http://www.whatwg.org/specs/web-workers/current-work/#kill-a-worker>"
> or "terminate a worker<http://www.whatwg.org/specs/web-workers/current-work/#terminate-a-worker>"
> algorithms defined below.
> 8. If worker global scope is actually a DedicatedWorkerGlobalScope<http://www.whatwg.org/specs/web-workers/current-work/#dedicatedworkerglobalscope> object
> (i.e. the worker is a dedicated worker), then enable the port message
> queue of the worker's implicit port.
>
> Basically, once the initial worker script returns, the worker's port is
> enabled and the normal message port event delivery mechanism kicks in
> (including dropping unhandled messages on the floor). I can't say whether
> Opera's behavior is correct or not based on your description - if you
> increase the timeout from 1 second to 10 seconds, do you still get the
> "onmessage message received"? If so, then that may be a bug in Opera because
> events delivered to workers without an onmessage handler set should be
> dropped.
>
> -atw
>
>
Hi Drew,
thanks for your reply!
If I set the timeout to 10 seconds, the message is still delivered in Opera.
... because events delivered to workers without an onmessage handler set
> should be dropped.
>
But if this is the case, then there is a big race-condition. Or I am totally
wrong.. :)
Let me give you an example:
The main script:
var myWorker = new Worker('worker.js');
myWorker.onmessage = function(evt) {..};
myWorker.postMessage('start');
//..
The web worker:
onmessage = function(evt) {
// do calculation
// post result
};
I guess this is the common structure: The web worker starts its work when it
receives a message.
But now the execution path could be:
main script web worker
var myWorker = new Worker('worker.js');
myWorker.onmessage = function(evt) {..};
myWorker.postMessage('start');
onmessage
= function(evt) { .. }
//..
And then the message from the main script is never received by the web
worker and it won't start its work.
Could that happen? From what you have said, I think it could.
Tobias
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.whatwg.org/pipermail/help-whatwg.org/attachments/20100803/e0eca1ac/attachment-0003.htm>
More information about the Help
mailing list