Re: [webkit-dev] WTF::callOnMainThread() and re-entrancy
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.orgwrote: On Mon, Mar 8, 2010 at 11:38 AM, Alexey Proskuryakov a...@webkit.orgwrote: 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
Re: [webkit-dev] WTF::callOnMainThread() and re-entrancy
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.orgwrote: 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.comwrote: 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.orgwrote: On Mon, Mar 8, 2010 at 11:38 AM, Alexey Proskuryakov a...@webkit.orgwrote: 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
Re: [webkit-dev] WTF::callOnMainThread() and re-entrancy
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? 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 ___ webkit-dev mailing list webkit-dev@lists.webkit.org http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev
Re: [webkit-dev] WTF::callOnMainThread() and re-entrancy
On Tue, Mar 9, 2010 at 11:13 AM, Alexey Proskuryakov a...@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. This was discussed somewhat off list between dumi, dimich, and myself (and whomever else dumi traded notes with). We were very surprised that tasks scheduled via postTask() were not executed in the same order as being scheduled. This change to postTask() was a shot at remedying that... but low and behold, something was apparently depending on the out of order execution? 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? 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 ___ 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
Re: [webkit-dev] WTF::callOnMainThread() and re-entrancy
On Tue, Mar 9, 2010 at 11:13 AM, Alexey Proskuryakov a...@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 ___ webkit-dev mailing list webkit-dev@lists.webkit.org http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev
Re: [webkit-dev] WTF::callOnMainThread() and re-entrancy
On 09.03.2010, at 11:23, Michael Nordman wrote: 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. This was discussed somewhat off list between dumi, dimich, and myself (and whomever else dumi traded notes with). We were very surprised that tasks scheduled via postTask() were not executed in the same order as being scheduled. Another way to fix just this aspect would be to piggy-back on existing task queue if it's non-empty, similar to what callOnMainThread() does. I'm not suggesting this, of course, as it still leaves us with a huge risk of race conditions and unexpected behaviors. - WBR, Alexey Proskuryakov ___ webkit-dev mailing list webkit-dev@lists.webkit.org http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev
Re: [webkit-dev] WTF::callOnMainThread() and re-entrancy
On Tue, Mar 9, 2010 at 11:34 AM, Dmitry Titov dim...@chromium.org wrote: On Tue, Mar 9, 2010 at 11:13 AM, Alexey Proskuryakov a...@webkit.orgwrote: 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. 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 CFRunLoopSources. 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... -atw 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 . Got it. Doesn't seem like we can affect the order of the CFRunLoopSource used by performSelectorOnMainThread(). - WBR, Alexey Proskuryakov ___ webkit-dev mailing list webkit-dev@lists.webkit.org http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev
Re: [webkit-dev] WTF::callOnMainThread() and re-entrancy
On 09.03.2010, at 11:51, Drew Wilson wrote: 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... As an unsubstantiated idea, we could also consider using a run loop observer. These can be set to fire at well defined points of run loop execution. - WBR, Alexey Proskuryakov ___ webkit-dev mailing list webkit-dev@lists.webkit.org http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev
Re: [webkit-dev] WTF::callOnMainThread() and re-entrancy
That's a great idea: http://developer.apple.com/Mac/library/documentation/CoreFoundation/Reference/CFRunLoopObserverRef/Reference/reference.html#//apple_ref/c/tdef/CFRunLoopActivity http://developer.apple.com/Mac/library/documentation/CoreFoundation/Reference/CFRunLoopObserverRef/Reference/reference.html#//apple_ref/c/tdef/CFRunLoopActivityThis gives us lots of places to hook. scheduleDispatchFunctionsFromMainThread() could be a no-op on the mac, if we just always invoke dispatchFunctionsFromMainThread() at a specified point in the loop (e.g. kCFRunLoopBeforeWaitingreference.html#//apple_ref/doc/c_ref/kCFRunLoopBeforeWaiting ). The only downside is that I'm not sure how to implement the yield for UI events behavior in dispatchFunctionsFromMainThread() if we're calling this from an observer - we actually need to have some kind of event generated to make sure we wake up. Maybe we could use scheduleDispatchFunctionsFromMainThread() to fire an event to make sure we have something to process, but actually do the processing from within the observer. -atw On Tue, Mar 9, 2010 at 11:55 AM, Alexey Proskuryakov a...@webkit.org wrote: On 09.03.2010, at 11:51, Drew Wilson wrote: 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... As an unsubstantiated idea, we could also consider using a run loop observer. These can be set to fire at well defined points of run loop execution. - WBR, Alexey Proskuryakov ___ webkit-dev mailing list webkit-dev@lists.webkit.org http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev
Re: [webkit-dev] WTF::callOnMainThread() and re-entrancy
I've tried to post a timer if the scheduleDispatchFunctionsFromMainThread comes on main thread - this fixes the test and it is a minimal change. Drew, let me know if you want to dig deeper in CFRunLoopObserver, otherwise I could whip up a patch (post a timer from main thread + postTask change from Dumi's patch). Dmitry On Tue, Mar 9, 2010 at 12:37 PM, Drew Wilson atwil...@google.com wrote: That's a great idea: http://developer.apple.com/Mac/library/documentation/CoreFoundation/Reference/CFRunLoopObserverRef/Reference/reference.html#//apple_ref/c/tdef/CFRunLoopActivity http://developer.apple.com/Mac/library/documentation/CoreFoundation/Reference/CFRunLoopObserverRef/Reference/reference.html#//apple_ref/c/tdef/CFRunLoopActivityThis gives us lots of places to hook. scheduleDispatchFunctionsFromMainThread() could be a no-op on the mac, if we just always invoke dispatchFunctionsFromMainThread() at a specified point in the loop (e.g. kCFRunLoopBeforeWaitinghttp://reference.html#//apple_ref/doc/c_ref/kCFRunLoopBeforeWaiting ). The only downside is that I'm not sure how to implement the yield for UI events behavior in dispatchFunctionsFromMainThread() if we're calling this from an observer - we actually need to have some kind of event generated to make sure we wake up. Maybe we could use scheduleDispatchFunctionsFromMainThread() to fire an event to make sure we have something to process, but actually do the processing from within the observer. -atw On Tue, Mar 9, 2010 at 11:55 AM, Alexey Proskuryakov a...@webkit.orgwrote: On 09.03.2010, at 11:51, Drew Wilson wrote: 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... As an unsubstantiated idea, we could also consider using a run loop observer. These can be set to fire at well defined points of run loop execution. - WBR, Alexey Proskuryakov ___ webkit-dev mailing list webkit-dev@lists.webkit.org http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev
Re: [webkit-dev] WTF::callOnMainThread() and re-entrancy
Yeah, that seems to be the least invasive. And we're already confident that creating a zero-delay timer won't cause event source starvation, since that's how postTask() used to work. -atw On Tue, Mar 9, 2010 at 12:53 PM, Dmitry Titov dim...@chromium.org wrote: I've tried to post a timer if the scheduleDispatchFunctionsFromMainThread comes on main thread - this fixes the test and it is a minimal change. Drew, let me know if you want to dig deeper in CFRunLoopObserver, otherwise I could whip up a patch (post a timer from main thread + postTask change from Dumi's patch). Dmitry On Tue, Mar 9, 2010 at 12:37 PM, Drew Wilson atwil...@google.com wrote: That's a great idea: http://developer.apple.com/Mac/library/documentation/CoreFoundation/Reference/CFRunLoopObserverRef/Reference/reference.html#//apple_ref/c/tdef/CFRunLoopActivity http://developer.apple.com/Mac/library/documentation/CoreFoundation/Reference/CFRunLoopObserverRef/Reference/reference.html#//apple_ref/c/tdef/CFRunLoopActivityThis gives us lots of places to hook. scheduleDispatchFunctionsFromMainThread() could be a no-op on the mac, if we just always invoke dispatchFunctionsFromMainThread() at a specified point in the loop (e.g. kCFRunLoopBeforeWaitinghttp://reference.html#//apple_ref/doc/c_ref/kCFRunLoopBeforeWaiting ). The only downside is that I'm not sure how to implement the yield for UI events behavior in dispatchFunctionsFromMainThread() if we're calling this from an observer - we actually need to have some kind of event generated to make sure we wake up. Maybe we could use scheduleDispatchFunctionsFromMainThread() to fire an event to make sure we have something to process, but actually do the processing from within the observer. -atw On Tue, Mar 9, 2010 at 11:55 AM, Alexey Proskuryakov a...@webkit.orgwrote: On 09.03.2010, at 11:51, Drew Wilson wrote: 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... As an unsubstantiated idea, we could also consider using a run loop observer. These can be set to fire at well defined points of run loop execution. - WBR, Alexey Proskuryakov ___ webkit-dev mailing list webkit-dev@lists.webkit.org http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev
Re: [webkit-dev] WTF::callOnMainThread() and re-entrancy
On 09.03.2010, at 12:37, Drew Wilson wrote: This gives us lots of places to hook. scheduleDispatchFunctionsFromMainThread() could be a no-op on the mac, if we just always invoke dispatchFunctionsFromMainThread() at a specified point in the loop (e.g. kCFRunLoopBeforeWaiting). Something would need to wake up the loop though. Run loop sources and timers do that automatically, but observers do not. - WBR, Alexey Proskuryakov ___ webkit-dev mailing list webkit-dev@lists.webkit.org http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev
Re: [webkit-dev] WTF::callOnMainThread() and re-entrancy
I saw a very similar bug recently regarding modal dialogs and focus/blur events: https://bugs.webkit.org/show_bug.cgi?id=33962. I think you will see the crash from that stacktrace with or without r55593 in place. For example, currently some mouse event handlers can fire underneath a window.alert on GMail. It's simple enough to check for page()-defersLoading() and suppress the task, but I am not sure how to re-enqueue the event to fire later. Maybe the PageLoadDeferrer should maintain a queue of things to do once it stops deferring (i.e. once the modal dialog is dismissed). - James On Mon, Mar 8, 2010 at 11:21 AM, Drew Wilson atwil...@google.com wrote: Hi all, This weekend I spent some time trying to track down a regression caused by r55593. In particular: http://trac.webkit.org/changeset/55593/trunk/WebCore/dom/Document.cpp This was a change to Document.postTask() to always use callOnMainThread() (previously, calls to postTask() on the main thread were using one-shot timers). We've since reverted r55593, but I've been playing around locally with that same change to Document.postTask(), and I noticed that it *appeared* that tasks posted via callOnMainThread() were still being executed even though the main thread was displaying a javascript alert. The end result is that if a worker thread was sending messages to the main thread via a message port, the event handlers for incoming messages would still be invoked (so we'd run javascript even though the javascript execution context should be blocked on the alert()). In my test, I ended up trying to display nested alert() dialogs, which resulted in a failed assertion. 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. Here's the stack from my nested call to alert(): #0 0x03ff073d in WebCore::DOMTimer::suspend (this=0x15c8a5b0) at /Volumes/source/chrome.git/src/third_party/WebKit/WebCore/page/DOMTimer.cpp:181 #1 0x046b2945 in WebCore::ScriptExecutionContext::suspendActiveDOMObjects (this=0x81d8434) at /Volumes/source/chrome.git/src/third_party/WebKit/WebCore/dom/ScriptExecutionContext.cpp:206 #2 0x04538ae5 in WebCore::PageGroupLoadDeferrer::PageGroupLoadDeferrer (this=0xbfffc6bc, page=0xc97940, deferSelf=true) at /Volumes/source/chrome.git/src/third_party/WebKit/WebCore/page/PageGroupLoadDeferrer.cpp:47 #3 0x03e0d977 in WebCore::Chrome::runJavaScriptAlert (this=0xc8ddb0, frame=0x805a600, messa...@0xbfffc790) at /Volumes/source/chrome.git/src/third_party/WebKit/WebCore/page/Chrome.cpp:264 #4 0x03ff6c2c in WebCore::DOMWindow::alert (this=0x147e23f0, messa...@0xbfffc790) at /Volumes/source/chrome.git/src/third_party/WebKit/WebCore/page/DOMWindow.cpp:795 #5 0x04266617 in WebCore::jsDOMWindowPrototypeFunctionAlert (exec=0x14f0c1b0, thisValue={u = {asEncodedJSValue = -8455721472, asDouble = -nan(0xe07ffee00), asBits = {payload = 134213120, tag = -2}}}, ar...@0xbfffc7bc) at /Volumes/source/chrome.git/src/third_party/WebKit/WebKitBuild/Debug/DerivedSources/WebCore/JSDOMWindow.cpp:8320 #6 0x00d8b166 in ?? () #7 0x0070bd6b in JSC::JITCode::execute (this=0x147a7690, registerFile=0x1473a7fc, callFrame=0x14f0c150, globalData=0x818e800, exception=0x818f60c) at JITCode.h:77 #8 0x006f542f in JSC::Interpreter::execute (this=0x1473a7f0, functionExecutable=0x147a7680, callFrame=0x81ed664, function=0x7fd5400, thisObj=0x7fd5200, ar...@0xbfffca64, scopeChain=0x147a8920, exception=0x818f60c) at /Volumes/source/chrome.git/src/third_party/WebKit/JavaScriptCore/interpreter/Interpreter.cpp:687 #9 0x0074d767 in JSC::JSFunction::call (this=0x7fd5400, exec=0x81ed664, thisValue={u = {asEncodedJSValue = -8455892480, asDouble = -nan(0xe07fd5200), asBits = {payload = 134042112, tag = -2}}}, ar...@0xbfffca64) at /Volumes/source/chrome.git/src/third_party/WebKit/JavaScriptCore/runtime/JSFunction.cpp:122 #10 0x0069d481 in JSC::call (exec=0x81ed664, functionObject={u = {asEncodedJSValue = -8455891968, asDouble = -nan(0xe07fd5400), asBits = {payload = 134042624, tag = -2}}}, callType=JSC::CallTypeJS, callda...@0xbfffca34, thisValue={u = {asEncodedJSValue = -8455892480, asDouble = -nan(0xe07fd5200), asBits = {payload = 134042112, tag = -2}}}, ar...@0xbfffca64) at /Volumes/source/chrome.git/src/third_party/WebKit/JavaScriptCore/runtime/CallData.cpp:39 #11 0x0429f5bb in WebCore::JSEventListener::handleEvent (this=0x15c31ef0, scriptExecutionContext=0x81d8434, event=0xc34d40) at /Volumes/source/chrome.git/src/third_party/WebKit/WebCore/bindings/js/JSEventListener.cpp:115 #12 0x04037da0 in WebCore::EventTarget::fireEventListeners (this=0x15c9c400,
Re: [webkit-dev] WTF::callOnMainThread() and re-entrancy
This is not surprising to me at all. The problem is even more complicated when you consider window.showModalDialog. I recently changed Chromium to suppress WebKit's shared timer during calls to alert, confirm, prompt, and the beforeunload prompt. That may be why you aren't seeing the problem with one-shot timers. However, that's a hack since the same can't be done for showModalDialog. It would be better if we extended the PageGroupLoadDeferrer (bad name btw) to suspend the right set of timers / callbacks properly. -Darin On Mon, Mar 8, 2010 at 11:21 AM, Drew Wilson atwil...@google.com wrote: Hi all, This weekend I spent some time trying to track down a regression caused by r55593. In particular: http://trac.webkit.org/changeset/55593/trunk/WebCore/dom/Document.cpp This was a change to Document.postTask() to always use callOnMainThread() (previously, calls to postTask() on the main thread were using one-shot timers). We've since reverted r55593, but I've been playing around locally with that same change to Document.postTask(), and I noticed that it *appeared* that tasks posted via callOnMainThread() were still being executed even though the main thread was displaying a javascript alert. The end result is that if a worker thread was sending messages to the main thread via a message port, the event handlers for incoming messages would still be invoked (so we'd run javascript even though the javascript execution context should be blocked on the alert()). In my test, I ended up trying to display nested alert() dialogs, which resulted in a failed assertion. 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. Here's the stack from my nested call to alert(): #0 0x03ff073d in WebCore::DOMTimer::suspend (this=0x15c8a5b0) at /Volumes/source/chrome.git/src/third_party/WebKit/WebCore/page/DOMTimer.cpp:181 #1 0x046b2945 in WebCore::ScriptExecutionContext::suspendActiveDOMObjects (this=0x81d8434) at /Volumes/source/chrome.git/src/third_party/WebKit/WebCore/dom/ScriptExecutionContext.cpp:206 #2 0x04538ae5 in WebCore::PageGroupLoadDeferrer::PageGroupLoadDeferrer (this=0xbfffc6bc, page=0xc97940, deferSelf=true) at /Volumes/source/chrome.git/src/third_party/WebKit/WebCore/page/PageGroupLoadDeferrer.cpp:47 #3 0x03e0d977 in WebCore::Chrome::runJavaScriptAlert (this=0xc8ddb0, frame=0x805a600, messa...@0xbfffc790) at /Volumes/source/chrome.git/src/third_party/WebKit/WebCore/page/Chrome.cpp:264 #4 0x03ff6c2c in WebCore::DOMWindow::alert (this=0x147e23f0, messa...@0xbfffc790) at /Volumes/source/chrome.git/src/third_party/WebKit/WebCore/page/DOMWindow.cpp:795 #5 0x04266617 in WebCore::jsDOMWindowPrototypeFunctionAlert (exec=0x14f0c1b0, thisValue={u = {asEncodedJSValue = -8455721472, asDouble = -nan(0xe07ffee00), asBits = {payload = 134213120, tag = -2}}}, ar...@0xbfffc7bc) at /Volumes/source/chrome.git/src/third_party/WebKit/WebKitBuild/Debug/DerivedSources/WebCore/JSDOMWindow.cpp:8320 #6 0x00d8b166 in ?? () #7 0x0070bd6b in JSC::JITCode::execute (this=0x147a7690, registerFile=0x1473a7fc, callFrame=0x14f0c150, globalData=0x818e800, exception=0x818f60c) at JITCode.h:77 #8 0x006f542f in JSC::Interpreter::execute (this=0x1473a7f0, functionExecutable=0x147a7680, callFrame=0x81ed664, function=0x7fd5400, thisObj=0x7fd5200, ar...@0xbfffca64, scopeChain=0x147a8920, exception=0x818f60c) at /Volumes/source/chrome.git/src/third_party/WebKit/JavaScriptCore/interpreter/Interpreter.cpp:687 #9 0x0074d767 in JSC::JSFunction::call (this=0x7fd5400, exec=0x81ed664, thisValue={u = {asEncodedJSValue = -8455892480, asDouble = -nan(0xe07fd5200), asBits = {payload = 134042112, tag = -2}}}, ar...@0xbfffca64) at /Volumes/source/chrome.git/src/third_party/WebKit/JavaScriptCore/runtime/JSFunction.cpp:122 #10 0x0069d481 in JSC::call (exec=0x81ed664, functionObject={u = {asEncodedJSValue = -8455891968, asDouble = -nan(0xe07fd5400), asBits = {payload = 134042624, tag = -2}}}, callType=JSC::CallTypeJS, callda...@0xbfffca34, thisValue={u = {asEncodedJSValue = -8455892480, asDouble = -nan(0xe07fd5200), asBits = {payload = 134042112, tag = -2}}}, ar...@0xbfffca64) at /Volumes/source/chrome.git/src/third_party/WebKit/JavaScriptCore/runtime/CallData.cpp:39 #11 0x0429f5bb in WebCore::JSEventListener::handleEvent (this=0x15c31ef0, scriptExecutionContext=0x81d8434, event=0xc34d40) at /Volumes/source/chrome.git/src/third_party/WebKit/WebCore/bindings/js/JSEventListener.cpp:115 #12 0x04037da0 in WebCore::EventTarget::fireEventListeners (this=0x15c9c400, event=0xc34d40) at
Re: [webkit-dev] WTF::callOnMainThread() and re-entrancy
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
Re: [webkit-dev] WTF::callOnMainThread() and re-entrancy
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.orgwrote: 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
Re: [webkit-dev] WTF::callOnMainThread() and re-entrancy
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.orgwrote: 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
Re: [webkit-dev] WTF::callOnMainThread() and re-entrancy
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.orgwrote: 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
Re: [webkit-dev] WTF::callOnMainThread() and re-entrancy
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.orgwrote: On Mon, Mar 8, 2010 at 11:38 AM, Alexey Proskuryakov a...@webkit.orgwrote: 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