XPCOM:nsIThreadManager: Difference between revisions

Line 386: Line 386:
=== dbaron: ===
=== dbaron: ===
So mrbkap was telling me at lunch about what's essentially the third bullet point of your comment to biesi above -- that you're making the concept of "modal event loop" even more powerful.  This actually scares me a good bit, because these modal event loops happen within another event -- an event that may have state on the stack (e.g., |this| parameters) that could be destroyed by the processing of further events, or may have posted events that rely on the event completing.  I really don't like the mix of programming models here that makes it very hard to write robust code, and I wish we could avoid this whole concept altogether rather than making it even more powerful, and thus more dangerous.  We already have crashes where frame trees get destroyed while processing an event that are related to the Windows API's way of doing the same thing, though (for, e.g., a DestroyWindow call or whatever it's called).
So mrbkap was telling me at lunch about what's essentially the third bullet point of your comment to biesi above -- that you're making the concept of "modal event loop" even more powerful.  This actually scares me a good bit, because these modal event loops happen within another event -- an event that may have state on the stack (e.g., |this| parameters) that could be destroyed by the processing of further events, or may have posted events that rely on the event completing.  I really don't like the mix of programming models here that makes it very hard to write robust code, and I wish we could avoid this whole concept altogether rather than making it even more powerful, and thus more dangerous.  We already have crashes where frame trees get destroyed while processing an event that are related to the Windows API's way of doing the same thing, though (for, e.g., a DestroyWindow call or whatever it's called).
==== darin: ====
Yup, I'm aware of that issue.  In fact, the problem already exists today.  There are some places in the code where WaitPLEvent + HandleEvent are called in a loop waiting for an event to process.  That bypasses PL_ProcessPendingEvents recursion restriction.  PopThreadEventQueue does not behave as you would expect either.  It can cause ProcessPendingEvents to run for all but the PLEventQueue that is the subject of the current call to PL_ProcessPendingEvents on the stack.  That defeats the purpose of the nested event queue in the first place.
The problem you describe with layout events also occurs for nsIStreamListener implementations.  It would be really wierd if OnDataAvailable were called recursively, or if OnDataAvailable were called while the consumer is calling nsIChannel::AsyncOpen.  These specific problems are dealt with in nsBaseChannel.cpp by temporarily suspending the channel during callbacks.  That suppresses recusive stream listener calls.
Do you have a suggestion that would allow us to prevent this problem?  Is there a better way to make XMLHttpRequest.send, document.load, window.alert, etc. appear modal to the calling Javascript?
For C++ consumers, we'd have to basically eliminate modal dialogs altogether to avoid this problem.  Today, we have bugs where downloads stale and get disconnected all because the browser popped up a modal dialog and the dialog was not closed promptly enough by the user.  That's just unacceptable.  And, nsIPromptService is frozen.
I think the answer is to be careful about making callbacks across XPCOM boundaries where event queues may be pumped.  Maybe the layout code needs to unwind the stack more before allowing such callbacks to happen so that it can be sure that event processing won't be the end of the world.
272

edits