RX: Avoid timing out non-kernel busy channels
[openafs.git] / src / rx / rx_event.h
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 /* Event package */
11
12 #ifndef _EVENT_
13 #define _EVENT_
14
15 #ifdef  KERNEL
16 #include "rx/rx_queue.h"
17 #include "rx/rx_clock.h"
18 #else /* KERNEL */
19 #include "rx_queue.h"
20 #include "rx_clock.h"
21 #endif /* KERNEL */
22
23 /* An event is something that will happen at (or after) a specified clock
24  * time, unless cancelled prematurely.  The user routine (*func)() is called
25  * with arguments (event, arg, arg1) when the event occurs.
26  * Warnings:
27  *   (1) The user supplied routine should NOT cause process preemption.
28  *   (2) The event passed to the user is still on the event queue at that
29  *       time.  The user must not remove (event_Cancel) it explicitly, but
30  *       the user may remove or schedule any OTHER event at this time.
31  */
32
33 struct rxevent {
34     struct rx_queue junk;       /* Events are queued */
35     struct clock eventTime;     /* When this event times out (in clock.c units) */
36     union {
37         void (*oldfunc) (struct rxevent *, void *, void *);
38         void (*newfunc) (struct rxevent *, void *, void *, int);
39     } func;                     /* Function to call when this expires */
40     void *arg;                  /* Argument to the function */
41     void *arg1;                 /* Another argument */
42     int arg2;                   /* An integer argument */
43     int newargs;                /* Nonzero if new-form arguments should be used */
44 };
45
46 /* We used to maintain a sorted list of events, but the amount of CPU
47  * required to maintain the list grew with the square of the number of
48  * connections. Now we keep a list of epochs, each epoch contains the
49  * events scheduled for a particular second. Each epoch contains a sorted
50  * list of the events scheduled for that epoch. */
51 struct rxepoch {
52     struct rx_queue junk;       /* Epochs are queued */
53     int epochSec;               /* each epoch spans one second */
54     struct rx_queue events;     /* list of events for this epoch */
55 };
56
57 /* Some macros to make macros more reasonable (this allows a block to be
58  * used within a macro which does not cause if statements to screw up).
59  * That is, you can use "if (...) macro_name(); else ...;" without
60  * having things blow up on the semi-colon. */
61
62 #ifndef BEGIN
63 #define BEGIN do {
64 #define END } while(0)
65 #endif
66
67 /* This routine must be called to initialize the event package.
68  * nEvents is the number of events to allocate in a batch whenever
69  * more are needed.  If this is 0, a default number (10) will be
70  * allocated. */
71 #if 0
72 extern void rxevent_Init( /* nEvents, scheduler */ );
73 #endif
74
75 /* Get the expiration time for the next event */
76 #if 0
77 extern void exevent_NextEvent( /* when */ );
78 #endif
79
80 /* Arrange for the indicated event at the appointed time.  When is a
81  * "struct clock", in the clock.c time base */
82 #if 0
83 extern struct rxevent *rxevent_Post( /* when, func, arg, arg1 */ );
84 #endif
85
86 /* Remove the indicated event from the event queue.  The event must be
87  * pending.  Also see the warning, above.  The event pointer supplied
88  * is zeroed.
89  */
90 #ifdef RX_ENABLE_LOCKS
91 #ifdef RX_REFCOUNT_CHECK
92 #define rxevent_Cancel(event_ptr, call, type)                       \
93         BEGIN                                       \
94             if (event_ptr) {                        \
95                 rxevent_Cancel_1(event_ptr, call, type);            \
96                 event_ptr = NULL;           \
97             }                                       \
98         END
99 #else /* RX_REFCOUNT_CHECK */
100 #define rxevent_Cancel(event_ptr, call, type)                       \
101         BEGIN                                       \
102             if (event_ptr) {                        \
103                 rxevent_Cancel_1(event_ptr, call, 0);       \
104                 event_ptr = NULL;           \
105             }                                       \
106         END
107 #endif /* RX_REFCOUNT_CHECK */
108 #else /* RX_ENABLE_LOCKS */
109 #define rxevent_Cancel(event_ptr, call, type)                       \
110         BEGIN                                       \
111             if (event_ptr) {                        \
112                 rxevent_Cancel_1(event_ptr, NULL, 0);       \
113                 event_ptr = NULL;           \
114             }                                       \
115         END
116 #endif /* RX_ENABLE_LOCKS */
117
118 /* The actions specified for each event that has reached the current clock
119  * time will be taken.  The current time returned by GetTime is used
120  * (warning:  this may be an old time if the user has not called
121  * clock_NewTime)
122  */
123 #if 0
124 extern int rxevent_RaiseEvents();
125 #endif
126
127 #endif /* _EVENT_ */