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::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=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
--
Ralf Bokelberg [EMAIL PROTECTED]
Flex Flash Consultant