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::dispatchEventFunction
[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::dispatchEventFunction
[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=00001890.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/
 

Reply via email to