Re: [flexcoders] Re: Bug in EventDispatcher? It shouldn't dispatch new Events if not at top of st
Ok, just to make sure what happens, i created a little test: private function onInitialize() { var ed1 : EventDispatcher = new EventDispatcher(); var ed2 : EventDispatcher = new EventDispatcher(); ed1.addEventListener('method', function():void { trace(11); }); ed1.addEventListener('method', function():void { trace(12); ed2.dispatchEvent( new Event('method')); }); ed1.addEventListener('method', function():void { trace(13); }); ed2.addEventListener('method', function():void { trace(21); }); ed2.addEventListener('method', function():void { trace(22); throw new Error('error'); }); ed2.addEventListener('method', function():void { trace(23); }); setInterval( function():void { trace('next event'); ed1.dispatchEvent( new Event('method')); }, 1000 ); } When i run this script, the following output is created: next event 11 12 21 22 Error: error -- at this point an alert box pops up asking if i want to continue - i answer yes 23 13 -- same again starting from 'next event' So, the exception is not breaking the event dispatching. The EventDispatcher seems to catch exceptions in event handlers. The Alert stops the whole event handling process and also the timer is stopped until i press continue. Do you see this alert too? Maybe the socket events are not stopped from beeing dispatched (in contrast to the timer events shown above), while the synchronous event handling still is beeing suspended? If you catch the error by yourself, so that no alert is shown, do you still see your problem? Cheers, Ralf. On 11/4/06, ncr100 [EMAIL PROTECTED] wrote: NOTE: Forgive me for replying twice. The Rich-Text Editor (Beta) seems to not be posting my replies, only the content. -Nick - - - Hi Ralf - thanks for the help figuring out and thinking about this problem - About your diagram, I am getting an exception in line 4 which caused unrolling up to line 3 which unexpectedly starts dispatching more events of types not dispatched in line 3. Yeah so I agree, all handlers registered to listen to a particular event type on a given object instance should be called when an event of that type is dispatched from that object. I also agree there should be no unexpected interruption of my single thread. And that if I synchronously dispatch an event then that will be handled by all listeners synchronously one after the other. But my understanding about asynchronous events (like new socket data, or Timer callbacks) is that they are delivered so they enter at the top of the execution stack, being passed to all registered event handlers synchronously one after the other. The problem is what I'm seeing is unexpected calls in the middle of my stack. Check this out: I'm handling an event of one type ProgressEvent.SOCKET_DATA and I need to do some dispatching of my own, a custom NavigationEvent event. The dispatcher correctly delivers my NavigationEvent synchronously while I wait blocked on that dispatch. But then I am surprised as the dispatcher takes the opportunity I've given it to dispatch not only my event but it starts to deliver other events: more ProgressEvent.SOCKET_DATA's that have queued up and other queued events. The socket data ProgressEvent is recursively delivered to my 'onSocketData', recursively because this new socket data event is delivered while I'm handling the prior socket data ProgressEvent listening 'onSocketData', in the same call stack, and it causes havoc. I wasn't expecting my synchronous call to the dispatcher to dispatch events other than the one I asked it to dispatch. Do what I say, not what you're doing. is what I am saying to myself as I see this. Diagrams do rock so I tweaked your illustration to match my situation: 1 OS dispatches event A 2 I handle event A .. there may be a Function.call higher in the stack .. 3 I dispatch event B synchronously 4 I handle event B deeper in this stack 5 I handle event B in my other registered listener after returning from 4 .. I throw a null pointer exception .. 6 I am unexpectedly handling event C after returning from 5. Then I crash. The dispatcher at 3 just dispatched C unexpectedly. I never return from my synchronous call to the dispatcher to the next line of code after 3 was called...also all of the code in 4-7 is in the same call stack started at 1. This event C is unexpected. I didn't dispatch it in 3, the OS/Adobe EventDispatcher did. I think the OS should have waited until I returned from my A handler entry point 2 before it dispatched C. To me that gotta send 'em all right now behavior is unusual. So, are you saying that it is in fact usual for C events to be dispatched at any opportunity I give the event dispatcher to dispatch events? And consequentially that I'm in store for inspection / tweaking to my
[flexcoders] Re: Bug in EventDispatcher? It shouldn't dispatch new Events if not at top of st
--- In flexcoders@yahoogroups.com, ncr100 [EMAIL PROTECTED] wrote: This is a complex one. Summary: I believe I'm not confused with try/catch, but am surprised that the EventDispatcher assumes our code is reentrant. Reentrant like the EventDispatcher is dispatching a system Event in the middle of me handling other events. So we're vulnerable to reentrant callbacks when we call EventDispatcher.dispatchEvent. Details: Normally when an null dereference happens an Error is propagated up the call stack to a catch handler. The bug is this: if in the middle of this call stack there happens to be an EventDispatcher.dispatchEvent call and the null pointer happens somewhere inside one of the listeners, then the Flash VM runtime thingy / implementation of dispatchEvent() itself seems to catch handle the Error, and takes the opportunity to dispatch a pending Events. In my case I've seen a ProgressEvent.SOCKET_DATA being dispatched because my server pumped out some data to me really quickly, though I assume any pending Event could be dispatched. This really causes havoc because our methods aren't reentrant; flash isn't multithreaded afaik and we don't think we have to write everything thread-safe. Here's an illustration I will walk through. At the start of the stack our DTVSocket.onSocketConnect listens for an ProgressEvent.SOCKET_DATA, and just got one. Notice for now the EventDispatcher [no source] in the middle of the stack trace. Capping off the stack trace, see our TextUtil.setText method ... it is doing something bad, and has just triggered a null pointer exception! dtv.util::TextUtil$/setText (BANG! null pointer exception) MarbachViewer/MarbachViewer::createChannelCanvas MarbachViewer/MarbachViewer::subscribeToChannel MarbachViewer/MarbachViewer::onConnected flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEven\ tFunction [no source] flash.events::EventDispatcher/dispatchEvent [no source] dtv.util::DTVSocket/dtv.util:DTVSocket::dispatchOnConnectedEvent dtv.util::DTVSocket/dtv.util:DTVSocket::onReceivedSessionTicket Function/http://adobe.com/AS3/2006/builtin::call [no source] dtv.util::DTVSocket/dtv.util:DTVSocket::onJSON dtv.util::DTVSocket/dtv.util:DTVSocket::onData dtv.util::DTVSocket/dtv.util:DTVSocket::onSocketData Now notice in this second shorter trace the stack has been unwound up to the dispatchEvent, but no further. onSocketData was just passed a second, new ProgressEvent.SOCKET_DATA. It must be that EventDispatcher.dispatchEvent caught my setText's null pointer exception and dispatched some additional socket data to my ProgressEvent.SOCKET_DATA listener. onSocketData is not thread safe. and bad stuff will happen very soon after in our code. dtv.util::DTVSocket/dtv.util:DTVSocket::onSocketData (WHOA! Not good) flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEven\ tFunction [no source] flash.events::EventDispatcher/dispatchEvent [no source] dtv.util::DTVSocket/dtv.util:DTVSocket::dispatchOnConnectedEvent dtv.util::DTVSocket/dtv.util:DTVSocket::onReceivedSessionTicket Function/http://adobe.com/AS3/2006/builtin::call [no source] dtv.util::DTVSocket/dtv.util:DTVSocket::onJSON dtv.util::DTVSocket/dtv.util:DTVSocket::onData dtv.util::DTVSocket/dtv.util:DTVSocket::onSocketData So the deal is this: Beware of event listener entry-points being called in a reentrant fashion if your app is handling an exception. Kind of like someone hitting you when you're down, flash is asking for your app to do stuff when it's crippled. A solution is to wrap the guts of all entry points in try/catch handlers. Or maybe only for high-frequency entry points. I looked thru these links for insight, perhaps hints indicating this kind of behavior but didn't find it: http://livedocs.macromedia.com/flex/2/docs/wwhelp/wwhimpl/js/html/wwhelp\ .htm?href=1890.html http://livedocs.macromedia.com/flex/2/langref/statements.html#try..catch\ ..finally Happy November! Nick -- Flexcoders Mailing List FAQ: http://groups.yahoo.com/group/flexcoders/files/flexcodersFAQ.txt Search Archives: http://www.mail-archive.com/flexcoders%40yahoogroups.com Yahoo! Groups Links * To visit your group on the web, go to: http://groups.yahoo.com/group/flexcoders/ * Your email settings: Individual Email | Traditional * To change settings online go to: http://groups.yahoo.com/group/flexcoders/join (Yahoo! ID required) * To change settings via email: mailto:[EMAIL PROTECTED] mailto:[EMAIL PROTECTED] * To unsubscribe from this group, send an email to: [EMAIL PROTECTED] * Your use of Yahoo! Groups is subject to: http://docs.yahoo.com/info/terms/
[flexcoders] Re: Bug in EventDispatcher? It shouldn't dispatch new Events if not at top of st
NOTE: Forgive me for replying twice. The Rich-Text Editor (Beta) seems to not be posting my replies, only the content. -Nick - - - Hi Ralf - thanks for the help figuring out and thinking about this problem - About your diagram, I am getting an exception in line 4 which caused unrolling up to line 3 which unexpectedly starts dispatching more events of types not dispatched in line 3. Yeah so I agree, all handlers registered to listen to a particular event type on a given object instance should be called when an event of that type is dispatched from that object. I also agree there should be no unexpected interruption of my single thread. And that if I synchronously dispatch an event then that will be handled by all listeners synchronously one after the other. But my understanding about asynchronous events (like new socket data, or Timer callbacks) is that they are delivered so they enter at the top of the execution stack, being passed to all registered event handlers synchronously one after the other. The problem is what I'm seeing is unexpected calls in the middle of my stack. Check this out: I'm handling an event of one type ProgressEvent.SOCKET_DATA and I need to do some dispatching of my own, a custom NavigationEvent event. The dispatcher correctly delivers my NavigationEvent synchronously while I wait blocked on that dispatch. But then I am surprised as the dispatcher takes the opportunity I've given it to dispatch not only my event but it starts to deliver other events: more ProgressEvent.SOCKET_DATA's that have queued up and other queued events. The socket data ProgressEvent is recursively delivered to my 'onSocketData', recursively because this new socket data event is delivered while I'm handling the prior socket data ProgressEvent listening 'onSocketData', in the same call stack, and it causes havoc. I wasn't expecting my synchronous call to the dispatcher to dispatch events other than the one I asked it to dispatch. Do what I say, not what you're doing. is what I am saying to myself as I see this. Diagrams do rock so I tweaked your illustration to match my situation: 1 OS dispatches event A 2 I handle event A .. there may be a Function.call higher in the stack .. 3 I dispatch event B synchronously 4 I handle event B deeper in this stack 5 I handle event B in my other registered listener after returning from 4 .. I throw a null pointer exception .. 6 I am unexpectedly handling event C after returning from 5. Then I crash. The dispatcher at 3 just dispatched C unexpectedly. I never return from my synchronous call to the dispatcher to the next line of code after 3 was called...also all of the code in 4-7 is in the same call stack started at 1. This event C is unexpected. I didn't dispatch it in 3, the OS/Adobe EventDispatcher did. I think the OS should have waited until I returned from my A handler entry point 2 before it dispatched C. To me that gotta send 'em all right now behavior is unusual. So, are you saying that it is in fact usual for C events to be dispatched at any opportunity I give the event dispatcher to dispatch events? And consequentially that I'm in store for inspection / tweaking to my event listener entry points, making them guard against recursive calls? My weekend will turn dark and gloomy if so. Or is there really a bug in the EventDispatcher code..? I'm suspicious of the Function.call() code as I've only seen this dispatch all pending behavior deeper in the stack after one of those is higher in the stack, as yet. Either way I think my weekend is gonna be gloomy. Or...? Danke, thanks again for the assistance, Nick San Francisco, CA USA -- Flexcoders Mailing List FAQ: http://groups.yahoo.com/group/flexcoders/files/flexcodersFAQ.txt Search Archives: http://www.mail-archive.com/flexcoders%40yahoogroups.com Yahoo! Groups Links * To visit your group on the web, go to: http://groups.yahoo.com/group/flexcoders/ * Your email settings: Individual Email | Traditional * To change settings online go to: http://groups.yahoo.com/group/flexcoders/join (Yahoo! ID required) * To change settings via email: mailto:[EMAIL PROTECTED] mailto:[EMAIL PROTECTED] * To unsubscribe from this group, send an email to: [EMAIL PROTECTED] * Your use of Yahoo! Groups is subject to: http://docs.yahoo.com/info/terms/
[flexcoders] Re: Bug in EventDispatcher? It shouldn't dispatch new Events if not at top of st
--- In flexcoders@yahoogroups.com, Ralf Bokelberg [EMAIL PROTECTED] wrote: Beeing able to dispatch events while we are dispatching an event is the expected behaviour. ActionScript doesn't have threads, so it's threadsafe per definition. In other words, it never happens, that an event interrupts a running method. If you dispatch an event while you are in another event handler, the new event is completely handled before the remaining handlers of the initial event are called. It's just simple method calls. 1 dispatch event 1 2 handle event 1 3 dispatch event 2 4 handle event 2 5 handle event 2 6handle event 1 7handle event 1 So what is the exact problem you see? An exception in line 2 doesn't stop the rest of the handling? Cheers, Ralf. On 11/4/06, ncr100 [EMAIL PROTECTED] wrote: This is a complex one. Summary: I believe I'm not confused with try/catch, but am surprised that the EventDispatcher assumes our code is reentrant. Reentrant like the EventDispatcher is dispatching a system Event in the middle of me handling other events. So we're vulnerable to reentrant callbacks when we call EventDispatcher.dispatchEvent. Details: Normally when an null dereference happens an Error is propagated up the call stack to a catch handler. The bug is this: if in the middle of this call stack there happens to be an EventDispatcher.dispatchEvent call and the null pointer happens somewhere inside one of the listeners, then the Flash VM runtime thingy / implementation of dispatchEvent() itself seems to catch handle the Error, and takes the opportunity to dispatch a pending Events. In my case I've seen a ProgressEvent.SOCKET_DATA being dispatched because my server pumped out some data to me really quickly, though I assume any pending Event could be dispatched. This really causes havoc because our methods aren't reentrant; flash isn't multithreaded afaik and we don't think we have to write everything thread-safe. Here's an illustration I will walk through. At the start of the stack our DTVSocket.onSocketConnect listens for an ProgressEvent.SOCKET_DATA, and just got one. Notice for now the EventDispatcher [no source] in the middle of the stack trace. Capping off the stack trace, see our TextUtil.setText method ... it is doing something bad, and has just triggered a null pointer exception! dtv.util::TextUtil$/setText (BANG! null pointer exception) MarbachViewer/MarbachViewer::createChannelCanvas MarbachViewer/MarbachViewer::subscribeToChannel MarbachViewer/MarbachViewer::onConnected flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEven\ tFunction [no source] flash.events::EventDispatcher/dispatchEvent [no source] dtv.util::DTVSocket/dtv.util:DTVSocket::dispatchOnConnectedEvent dtv.util::DTVSocket/dtv.util:DTVSocket::onReceivedSessionTicket Function/http://adobe.com/AS3/2006/builtin::call [no source] dtv.util::DTVSocket/dtv.util:DTVSocket::onJSON dtv.util::DTVSocket/dtv.util:DTVSocket::onData dtv.util::DTVSocket/dtv.util:DTVSocket::onSocketData Now notice in this second shorter trace the stack has been unwound up to the dispatchEvent, but no further. onSocketData was just passed a second, new ProgressEvent.SOCKET_DATA. It must be that EventDispatcher.dispatchEvent caught my setText's null pointer exception and dispatched some additional socket data to my ProgressEvent.SOCKET_DATA listener. onSocketData is not thread safe. and bad stuff will happen very soon after in our code. dtv.util::DTVSocket/dtv.util:DTVSocket::onSocketData(WHOA! Not good) flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEven\ tFunction [no source] flash.events::EventDispatcher/dispatchEvent [no source] dtv.util::DTVSocket/dtv.util:DTVSocket::dispatchOnConnectedEvent dtv.util::DTVSocket/dtv.util:DTVSocket::onReceivedSessionTicket Function/http://adobe.com/AS3/2006/builtin::call [no source] dtv.util::DTVSocket/dtv.util:DTVSocket::onJSON dtv.util::DTVSocket/dtv.util:DTVSocket::onData dtv.util::DTVSocket/dtv.util:DTVSocket::onSocketData So the deal is this: Beware of event listener entry-points being called in a reentrant fashion if your app is handling an exception. Kind of like someone hitting you when you're down, flash is asking for your app to do stuff when it's crippled. A solution is to wrap the guts of all entry points in try/catch handlers. Or maybe only for high-frequency entry points. I looked thru these links for insight, perhaps hints indicating this kind of behavior but didn't find it: http://livedocs.macromedia.com/flex/2/docs/wwhelp/wwhimpl/js/html/wwhelp\ .htm?href=1890.html http://livedocs.macromedia.com/flex/2/langref/statements.html#try..catch\ ..finally Happy November! Nick -- Flexcoders Mailing List FAQ: