Standard Event Driven Object Library for D
Brian White
bcwhite at pobox.com
Tue Apr 1 23:39:10 PDT 2008
> I'm seeing two types of events: notifications and responsibilities.
>
> A notification just says "This happened, and I don't care if anyone
> reacts to it." std.signals does okay with that, except for a few bits of
> ugliness and the fact that it places undesirable dependencies between
> objects.
>
> A responsibility says "This happened, and someone (but only one) should
> take care of it." It might be an error if nobody handles it. Something
> can take a look at a responsibility before determining that it's
> somebody else's problem.
That's a good distinction. The word "event" is too loose.
> However, I don't see the utility in automatically removing a listener
> when it claims that it cannot handle a particular responsibility. Not
> handling a particular message and not handling any further messages are
> different use cases.
You could be right. That's why I want to get other people involved; I
can't see everything. Here was my reasoning...
When doing embedded controller work, I used a very similar design for
passing data up a TCP/IP stack to the app. During profiling, I found
that a significant amount of the CPU time was being spent in the
dispatching of i/o events that just got ignored. By changing the event
handlers to say "thanks, but don't send me any more", I was able to save
something like 10-15% CPU time. (Profiling never shows you what you
expect. :-)
In the case of a C++ program in a proper operating system, think of the
"write" event from a select call. If you leave it active but write
nothing, you'll just get the event again and again and again. You'll
spin CPU instead of letting the OS notify you.
There are other solutions, of course. In my C++ library, you had to
make a call to clear the "write callback" when you didn't want such
events. That would work it's way down the stack of objects until it
cleared the respective bit from the "write" fd_set. This ended up being
somewhat clumsy to implement though because objects are responsible for
themselves, it was never anything the library user had to worry about.
Instead, I thought I'd take a simpler approach of just requesting "all
or nothing" and letting the system take care of turning off those that
aren't wanted when they occurred.
I figured it would also be beneficial to minimize the number of
potential loops in the object stack. If calling "DisableEvent" from
within an event handler, you run the risk of that method generating some
different event and calling back up the stack yet again. By returning
the status, then any other events generated aren't a loop.
In the presence of a proper event queue, loops never happens because the
next item on the queue doesn't get processed until the previous one
completes. Using callbacks, however, this is not the case as every
"event" is always processed directly and immediately.
-- Brian
More information about the Digitalmars-d
mailing list