/* * Copyright 2000, International Business Machines Corporation and others. * All Rights Reserved. * * This software has been released under the terms of the IBM Public * License. For details, see the LICENSE file in the top-level source * directory or online at http://www.openafs.org/dl/license10.html */ /* Event package */ #ifndef _EVENT_ #define _EVENT_ #ifdef KERNEL #include "rx/rx_queue.h" #include "rx/rx_clock.h" #else /* KERNEL */ #include "rx_queue.h" #include "rx_clock.h" #endif /* KERNEL */ /* An event is something that will happen at (or after) a specified clock * time, unless cancelled prematurely. The user routine (*func)() is called * with arguments (event, arg, arg1) when the event occurs. * Warnings: * (1) The user supplied routine should NOT cause process preemption. * (2) The event passed to the user is still on the event queue at that * time. The user must not remove (event_Cancel) it explicitly, but * the user may remove or schedule any OTHER event at this time. */ struct rxevent { struct rx_queue junk; /* Events are queued */ struct clock eventTime; /* When this event times out (in clock.c units) */ union { void (*oldfunc) (struct rxevent *, void *, void *); void (*newfunc) (struct rxevent *, void *, void *, int); } func; /* Function to call when this expires */ void *arg; /* Argument to the function */ void *arg1; /* Another argument */ int arg2; /* An integer argument */ int newargs; /* Nonzero if new-form arguments should be used */ }; /* We used to maintain a sorted list of events, but the amount of CPU * required to maintain the list grew with the square of the number of * connections. Now we keep a list of epochs, each epoch contains the * events scheduled for a particular second. Each epoch contains a sorted * list of the events scheduled for that epoch. */ struct rxepoch { struct rx_queue junk; /* Epochs are queued */ int epochSec; /* each epoch spans one second */ struct rx_queue events; /* list of events for this epoch */ }; /* Some macros to make macros more reasonable (this allows a block to be * used within a macro which does not cause if statements to screw up). * That is, you can use "if (...) macro_name(); else ...;" without * having things blow up on the semi-colon. */ #ifndef BEGIN #define BEGIN do { #define END } while(0) #endif /* This routine must be called to initialize the event package. * nEvents is the number of events to allocate in a batch whenever * more are needed. If this is 0, a default number (10) will be * allocated. */ #if 0 extern void rxevent_Init( /* nEvents, scheduler */ ); #endif /* Get the expiration time for the next event */ #if 0 extern void exevent_NextEvent( /* when */ ); #endif /* Arrange for the indicated event at the appointed time. When is a * "struct clock", in the clock.c time base */ #if 0 extern struct rxevent *rxevent_Post( /* when, func, arg, arg1 */ ); #endif /* Remove the indicated event from the event queue. The event must be * pending. Also see the warning, above. The event pointer supplied * is zeroed. */ #ifdef RX_ENABLE_LOCKS #ifdef RX_REFCOUNT_CHECK #define rxevent_Cancel(event_ptr, call, type) \ BEGIN \ if (event_ptr) { \ rxevent_Cancel_1(event_ptr, call, type); \ event_ptr = NULL; \ } \ END #else /* RX_REFCOUNT_CHECK */ #define rxevent_Cancel(event_ptr, call, type) \ BEGIN \ if (event_ptr) { \ rxevent_Cancel_1(event_ptr, call, 0); \ event_ptr = NULL; \ } \ END #endif /* RX_REFCOUNT_CHECK */ #else /* RX_ENABLE_LOCKS */ #define rxevent_Cancel(event_ptr, call, type) \ BEGIN \ if (event_ptr) { \ rxevent_Cancel_1(event_ptr, NULL, 0); \ event_ptr = NULL; \ } \ END #endif /* RX_ENABLE_LOCKS */ /* The actions specified for each event that has reached the current clock * time will be taken. The current time returned by GetTime is used * (warning: this may be an old time if the user has not called * clock_NewTime) */ #if 0 extern int rxevent_RaiseEvents(); #endif #endif /* _EVENT_ */