Another alternative is for us to add a flag to scheduleDispatchFunctionsOnMainThread() which is passed as true in the case where we are calling it from dispatchFunctionsOnMainThread():
// If we are running accumulated functions for too long so UI may become unresponsive, we need to // yield so the user input can be processed. Otherwise user may not be able to even close the window. // This code has effect only in case the scheduleDispatchFunctionsOnMainThread() is implemented in a way that // allows input events to be processed before we are back here. if (currentTime() - startTime > maxRunLoopSuspensionTime) { scheduleDispatchFunctionsOnMainThread(true); // delay = true break; } } That way, in the case where we are in some kind of tight loop and we want to yield anyway to let UI events happen, we could instead yield for (say) 10ms to make sure lower priority events have a chance to be dispatched. Alexey, what do you think? My preference would be to use a lower priority event instead of a delay, but I don't know enough about Cocoa programming to know whether that's possible. -atw On Tue, Mar 9, 2010 at 9:45 AM, Drew Wilson <atwil...@google.com> 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 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 <dim...@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 <atwil...@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 <dim...@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 <atwil...@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 <dim...@chromium.org>wrote: >>>>> >>>>>> On Mon, Mar 8, 2010 at 11:38 AM, Alexey Proskuryakov >>>>>> <a...@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@lists.webkit.org >>>>>>> http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev >>>>>>> >>>>>> >>>>>> >>>>> >>>> >>> >> >
_______________________________________________ webkit-dev mailing list webkit-dev@lists.webkit.org http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev