[webkit-dev] WTF::callOnMainThread() and re-entrancy

Dmitry Titov dimich at chromium.org
Tue Mar 9 11:34:35 PST 2010

On Tue, Mar 9, 2010 at 11:13 AM, Alexey Proskuryakov <ap at webkit.org> wrote:

> On 09.03.2010, at 9:45, Drew Wilson wrote:
>  Yeah, it's a race condition - it seems to all depend on whether the worker
>> resource gets loaded before the postMessage loop starts. Failure rate is
>> around 30-50% on my machine.
> It would help to have a more detailed description of the problem. I've been
> following the discussion in bugs and in this thread, but I'm still unsure
> about some aspects of it.
> Seems that there are two issues at hand:
> 1) We feel the need to change how Document::postTask() behaves, because
> otherwise, the patch for <https://bugs.webkit.org/show_bug.cgi?id=34726>
> doesn't work. We feel the need because it makes little sense for it to have
> drastically different behavior depending on what thread it's called from.
> It feels like a good change to make indeed, but I'm surprised that it
> apparently went through review unmentioned and unquestioned. The questions
> to ask are why exactly it was needed, and whether there are other ways to
> fix bug 34726.
> 2) if we make that change, the worker-cloneport.html test starts to fail.
> I didn't attempt to debug this myself, and I don't quite understand the
> problem description. I see only one postMessage loop in the test, and it's
> in worker code. How can it be executed before the worker resource gets
> loaded?

There is a MessageChannel which sets the same onmessage handler for both
ports, and that handler 'reflects' the received message to the sender
through the channel. Then the test starts this ping-pong by sending a single
message through. As a result, there is always a message in transit - they
are delivered via Document::postTask. So at every moment there is at least
one task in the postTask's queue, and executing that task immediately adds a
new task (since the onmessage handler posts the next message through the
MessageChannel). All this ping-pong happens on main thread, while worker
gets loaded.

That means we always exit the loop processing the tasks in
dispatchFunctionsFromMainThread() via timeout, and there are always
a performSelectorOnMainThread in the RunLoop queue.

The interesting thing I don't yet understand is why one-shot timer
(implemented via CFRunLoopAddTimer), when used for queueing in
Docuemnt::postTask works fine and performSelectorOnMainThread causes hang of
the test.

>  It looks like events have priority in Cocoa, and I'm guessing that
>> performSelectorOnMainThread() creates events with a higher priority than
>> those generated by URLConnection, which can lead to starvation. I'm not
>> certain what the right fix is, other than to maybe use a different method of
>> dispatching events other than performSelectorOnMainThread that lets us set a
>> lower priority?
> These main thread calls do not use events for processing. CF/NSRunLoop has
> a concept of run loop sources, which can generate events or perform other
> actions, see <
> http://developer.apple.com/mac/library/documentation/CoreFoundation/Reference/CFRunLoopRef/Reference/reference.html>
> and <
> http://developer.apple.com/Mac/library/documentation/CoreFoundation/Reference/CFRunLoopSourceRef/Reference/reference.html
> >.
> - WBR, Alexey Proskuryakov
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-dev/attachments/20100309/3782d77b/attachment.html>

More information about the webkit-dev mailing list