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