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

Drew Wilson atwilson at google.com
Tue Mar 9 09:45:45 PST 2010


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 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?

-atw

On Mon, Mar 8, 2010 at 7:24 PM, Dmitry Titov <dimich at chromium.org> wrote:

> At least user input is dispatched even if there are outstanding
> performSelectorOnMainThread calls:
> https://bugs.webkit.org/show_bug.cgi?id=23705
>
> With the change in postTask, the cloneport test does not always hang - on
> my machine it's 50-50. There is some racing condition somewhere perhaps...
>
>
> On Mon, Mar 8, 2010 at 5:29 PM, Drew Wilson <atwilson at google.com> wrote:
>
>> Following up with a related note - does anyone have any insight into how
>> the Cocoa event loop dispatches events from different sources? In
>> particular, I have a test (worker-cloneport.html) which posts a port back
>> and forth between two endpoints (both on the main thread).
>>
>> With the change to Document.postTask() I described earlier in this thread,
>> this test results in there always being a pending event (posted via
>> performSelectorOnMainThread) when we re-enter the cocoa runloop. It appears
>> that the run loop *always* dispatches this event before dispatching events
>> from NSURLConnection - the result is that any pending resource loads never
>> complete.
>>
>> Is there some kind of prioritization within the cocoa run loop so that
>> certain types of events (like NSURLConnection events) if there are no
>> pending events of other types?
>>
>> -atw
>>
>>
>> On Mon, Mar 8, 2010 at 2:08 PM, Dmitry Titov <dimich at chromium.org> wrote:
>>
>>> Many tasks are just fine to execute while modal UI is present. For
>>> example, XHR in a Worker probably should not be frozen by an alert on the
>>> parent page. That posts tasks to main thread for loader.
>>> Also, it's unclear if a task can be simply delayed or in fact some other
>>> action should be performed at resume point - for example, timers
>>> re-calculate the next fire time.
>>>
>>> Maybe there can be a generic mechanism for tasks to participate in
>>> suspend/resume... It'd require a better definition of the events - for
>>> example, is there a difference between "suspense on modal UI" and "suspense
>>> on going into BF cache"? Probably there is.
>>>
>>> Dmitrty
>>>
>>>
>>> On Mon, Mar 8, 2010 at 1:45 PM, Drew Wilson <atwilson at google.com> wrote:
>>>
>>>> So the implication is that every single place that uses tasks has to
>>>> have an associated activeDOMObject() or other hooks in
>>>> ScriptExecutionContext so it can get suspend/resume calls and try to queue
>>>> up the tasks for later? That seems a) hard (since not everything that uses
>>>> tasks necessarily has an activeDOMObject), and b) fragile because we'll
>>>> undoubtedly miss cases -- there's something like 70 calls to
>>>> callOnMainThread()/postTask() in the WebCore code.
>>>>
>>>> Is there no way to do something at a lower level? callOnMainThread()
>>>> already keeps a queue of pending callbacks, so it seems like just not
>>>> dispatching those callbacks might be better? It's tricky because you don't
>>>> necessarily know which ScriptExecutionContext a task is destined for at that
>>>> low level.
>>>>
>>>> -atw
>>>>
>>>>
>>>> On Mon, Mar 8, 2010 at 1:24 PM, Dmitry Titov <dimich at chromium.org>wrote:
>>>>
>>>>> On Mon, Mar 8, 2010 at 11:38 AM, Alexey Proskuryakov <ap at webkit.org>wrote:
>>>>>
>>>>>>
>>>>>> On 08.03.2010, at 11:21, Drew Wilson wrote:
>>>>>>
>>>>>>  So, my question is: does it surprise anyone that tasks posted via
>>>>>>> callOnMainThread() are getting executed even though there's a modal dialog
>>>>>>> shown? And is there anything I should be doing in my task handler to make
>>>>>>> sure we aren't re-entering JS execution inappropriately in these cases? I'm
>>>>>>> just concerned that the way we're posting tasks from worker threads to the
>>>>>>> main thread may cause reentrancy problems.
>>>>>>>
>>>>>>
>>>>>> It is not correct to deliver messages from worker threads when an
>>>>>> alert or a modal window is displayed. It may be ok for modal dialogs that
>>>>>> are triggered asynchronously (such as credentials dialog).
>>>>>>
>>>>>> We have a manual test regression for a related issue,
>>>>>> WebCore/manual-tests/js-timers-beneath-modal-dialog.html. You can compare
>>>>>> how timers work, and how worker messages are delivered to find out how to
>>>>>> fix the problem.
>>>>>>
>>>>>
>>>>> Timers are suspended by
>>>>> ScriptExecutionContext::suspendActiveDOMObjects/resumeActiveDOMObjects from
>>>>> PageGroupLoadDeferrer. So the context (Document) knows when it is suspended
>>>>> and when it gets resumed.
>>>>> It seems the task to process accumulated port messages can be postponed
>>>>> until resume.
>>>>>
>>>>>
>>>>>
>>>>>> - WBR, Alexey Proskuryakov
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> webkit-dev mailing list
>>>>>> webkit-dev at lists.webkit.org
>>>>>> http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-dev/attachments/20100309/bc941b52/attachment.html>


More information about the webkit-dev mailing list