Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 19 Aug 1999 12:56:56 -0700
From:      Mike Smith <mike@smith.net.au>
To:        Julian Elischer <julian@whistle.com>
Cc:        current@FreeBSD.ORG
Subject:   Re: HEADS UP: at_shutdown going away 
Message-ID:  <199908191956.MAA07723@dingo.cdrom.com>
In-Reply-To: Your message of "Thu, 19 Aug 1999 12:11:49 PDT." <Pine.BSF.3.95.990819120839.13522B-100000@current1.whistle.com> 

next in thread | previous in thread | raw e-mail | index | archive | help
> there was external code at TRW but I don't know if it is still in use..
> 
> We have uses of it here at whistle too. (that's why I wrote it..)
> but I guess I can handle them...
> 
> why the change?
> If you re-aranged the arguments you'd have EVENTHANDLER_REGISTER ==
> at_shutdown_pri.

It has to do with the way that I deal with arbitrary arguments to the 
called-out functions, in order to save all the crap that the caller 
might have to perform with constructing an argument structure and then 
passing a pointer to it.

It's easier to explain like this (backslashes elided):

#define EVENTHANDLER_DECLARE(name, type)
struct eventhandler_entry_ ## name
{
    struct eventhandler_entry   ee;
    type                eh_func;
};

#define EVENTHANDLER_INVOKE(name, args...)
{
    struct eventhandler_list *el;
    struct eventhandler_entry *ep;

    if ((el = eventhandler_find_list(#name)) != NULL) {
        for (ep = TAILQ_FIRST(&(el->el_entries));
             ep != NULL;
             ep = TAILQ_NEXT(ep, ee_link)) {
            ((struct eventhandler_entry_ ## name *)ep)->
		eh_func(ep->ee_arg , ## args);
        }                                                                       
    }                                                                           
}

ie. the called-out function isn't forced to be of any particular type 
other than that it can't return anything and it's first argument must 
be void *.  Unfortunately, the way that macro varargs works makes it 
hard to put the variable arguments _first_ (and I wouldn't want to do 
that since it would make calling out to a real varargs function 
impossible).

> what are the selectabel (available) event queues?

That's one of the nicer features of this mechanism; you can create them
more or less on the fly.  There are actually two implementations; one
optimised for speed which requires the queue to be present in the linked
objects (effectively it does the name->list translation using the
linker), the other optimised for convenience which just requires the
queue to be defined somewhere in a shared header (to get the queue entry
type into scope).  This latter mechanism means that eg. I can say

EVENTHANDLER_REGISTER(pwrmgmt_suspend, foosuspend, foo_softc, 0)

from within a driver, even if the code that's going to invoke this 
handler hasn't been loaded yet.  By tying events to named queues rather 
than to implementations, it helps soften the boundaries - in this 
example the caller that eventually invokes the pwrmgmt_suspend handlers 
will initially be APM, but it may later be ACPI, or something totally 
different on eg. the Alpha, or an OpenFirmware system. 

-- 
\\  The mind's the standard       \\  Mike Smith
\\  of the man.                   \\  msmith@freebsd.org
\\    -- Joseph Merrick           \\  msmith@cdrom.com




To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199908191956.MAA07723>