[html5] Web Workers: Race-Condition setting onmessage handler?

Dmitry Titov dimich at chromium.org
Thu Aug 5 11:40:25 PDT 2010


I can try to say the same thing Drew is saying shorter: Workers queue all
messages from main page until the moment the "initial script" is run.
Initial script is the JS code outside of any function. If that initial
script registers 'onmessage', all queued messages are delivered. If it
doesn't - queued massages are dropped.

This means the worker better register 'onmessage' in its initial code, not
from some other event handler.

Dmitry

On Tue, Aug 3, 2010 at 2:09 PM, Drew Wilson <atwilson at chromium.org> wrote:

>
> On Tue, Aug 3, 2010 at 1:40 PM, Rik Sagar <org.whatwg at sagar.org> wrote:
>
>>
>> I would expect in this example that the *Worker got loaded*  message
>> should be dropped on the floor.
>>
>> I would expect exactly the opposite - that message should be delivered.
>
> Here's the way I look at worker messaging (and events in general) - each
> javascript context (or "thread" if you will) has what amounts to an event
> loop. When your javascript code returns from an event handler (or, in the
> case of worker script, returns from an event handler or returns from
> executing the initial block of script), you drop back in to your event loop
> and start dispatching events.
>
> There are a number of things that can generate events (that can be "event
> sources") - for example, a timer is an event source. MessagePorts (both
> explicit MessagePorts and also implicit ones for Dedicated Workers) are
> event sources, too. When you queue up an event for a MessagePort, it becomes
> an active event source (meaning that when the associated javascript context
> re-enters its event loop, that MessagePort can cause an onmessage event to
> be generated). The event loop traverses the various associated event sources
> for the javascript context (timers, message ports, etc) and fires off an
> event from one of the event sources (the spec doesn't specify an ordering
> here, so it's up to the UA to decide how to prioritize various event
> sources) - when it fires off the event, any handlers associated with that
> event will receive the event, and if there are no handlers the typical
> default handling of the event occurs (gets dropped on the floor, or maybe
> gets bubbled up in the case of DOM events, etc).
>
> So, in your case above, here's what happens - webapp_main creates a worker
> and then adds an "onmessage" handler to the worker object. Now,
> webapp_worker runs, sets up an onmessage handler (which, btw, will never be
> executed since you never send any messages to the worker in your example),
> then fires off a "Worker got loaded" message to webapp_main. Even if this
> code is executed before webapp_main has set its onmessage handler, the event
> will not get dropped on the floor - remember that all postMessage() does is
> put the event in the MessagePort's queue, then make that MessagePort an
> active event source. So as long as webapp_main sets an onmessage handler
> before it returns back to the event loop, there's no way for the event to
> get dropped on the floor because the event isn't even dispatched until you
> get back to the event loop.
>
> Hopefully this helps clear up some of the confusion - it's important to
> understand that the various flavors of postMessage() are entirely
> asynchronous and rely on events being dispatched from the event loop.
>
>
>
>> Thanks,
>> Rik.
>>
>>
>>
>>
>> Rik Sagar, San Jose, CA 95124
>> Visit : http://sagar.org/
>>
>>
>>
>> On Mon, Aug 2, 2010 at 10:09 AM, 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
>>>
>>>
>>> _______________________________________________
>>> Help mailing list
>>> Help at lists.whatwg.org
>>> http://lists.whatwg.org/listinfo.cgi/help-whatwg.org
>>>
>>>
>>
>
> _______________________________________________
> Help mailing list
> Help at lists.whatwg.org
> http://lists.whatwg.org/listinfo.cgi/help-whatwg.org
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.whatwg.org/pipermail/help-whatwg.org/attachments/20100805/8239c323/attachment-0002.htm>


More information about the Help mailing list