[webkit-dev] WTF::callOnMainThread() and re-entrancy
atwilson at google.com
Tue Mar 9 11:51:19 PST 2010
On Tue, Mar 9, 2010 at 11:34 AM, Dmitry Titov <dimich at chromium.org> wrote:
> 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
> 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.
I'm guessing that timers aren't implemented as a CFRunLoopSource, so have
different behavior (they won't starve CFRunLoopSources and won't be starved
by them). Whereas performSelectorOnMainThread can starve other
That actually is an interesting idea - perhaps we could implement
scheduleDispatchFunctionsFromMainThread() using a 0-delay timer in the case
where it's called from the main thread...
>> 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 <
>> and <
Got it. Doesn't seem like we can affect the order of the CFRunLoopSource
used by performSelectorOnMainThread().
> - WBR, Alexey Proskuryakov
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the webkit-dev