]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/sys/eventhandler.h
This commit was generated by cvs2svn to compensate for changes in r56083,
[FreeBSD/FreeBSD.git] / sys / sys / eventhandler.h
1 /*-
2  * Copyright (c) 1999 Michael Smith <msmith@freebsd.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28
29 #include <sys/queue.h>
30
31 #ifndef SYS_EVENTHANDLER_H
32 #define SYS_EVENTHANDLER_H
33
34 struct eventhandler_entry 
35 {
36     TAILQ_ENTRY(eventhandler_entry)     ee_link;
37     int                                 ee_priority;
38     void                                *ee_arg;
39 };
40
41 struct eventhandler_list 
42 {
43     TAILQ_ENTRY(eventhandler_list)      el_link;
44     char                                *el_name;
45     int                                 el_flags;
46 #define EHE_INITTED     (1<<0)
47     TAILQ_HEAD(,eventhandler_entry)     el_entries;
48 };
49
50 typedef struct eventhandler_entry       *eventhandler_tag;
51
52 /* 
53  * Fast handler lists require the eventhandler list be present
54  * at link time.  They don't allow addition of entries to
55  * unknown eventhandler lists, ie. each list must have an 
56  * "owner".
57  *
58  * Fast handler lists must be defined once by the owner 
59  * of the eventhandler list, and the declaration must be in 
60  * scope at any point the list is manipulated.
61  */
62 #define EVENTHANDLER_FAST_DECLARE(name, type)                   \
63 extern struct eventhandler_list Xeventhandler_list_ ## name ;   \
64 struct eventhandler_entry_ ## name                              \
65 {                                                               \
66     struct eventhandler_entry   ee;                             \
67     type                eh_func;                                \
68 };
69
70 #define EVENTHANDLER_FAST_DEFINE(name, type)                    \
71 struct eventhandler_list Xeventhandler_list_ ## name = { #name };
72
73 #define EVENTHANDLER_FAST_INVOKE(name, args...)                         \
74 do {                                                                    \
75     struct eventhandler_list *_el = &Xeventhandler_list_ ## name ;      \
76     struct eventhandler_entry *_ep = TAILQ_FIRST(&(_el->el_entries));   \
77                                                                         \
78     while (_ep != NULL) {                                               \
79         ((struct eventhandler_entry_ ## name *)_ep)->eh_func(_ep->ee_arg , ## args); \
80         _ep = TAILQ_NEXT(_ep, ee_link);                                 \
81     }                                                                   \
82 } while (0);
83
84 #define EVENTHANDLER_FAST_REGISTER(name, func, arg, priority) \
85     eventhandler_register(Xeventhandler_list_ ## name, #name, func, arg, priority)
86
87 #define EVENTHANDLER_FAST_DEREGISTER(name, tag) \
88     eventhandler_deregister(Xeventhandler_list ## name, tag)
89
90
91 /*
92  * Slow handlerss are entirely dynamic; lists are created
93  * when entries are added to them, and thus have no concept of "owner",
94  *
95  * Slow handlerss need to be declared, but do not need to be defined. The
96  * declaration must be in scope wherever the handler is to be invoked.
97  */
98 #define EVENTHANDLER_DECLARE(name, type)        \
99 struct eventhandler_entry_ ## name              \
100 {                                               \
101     struct eventhandler_entry   ee;             \
102     type                eh_func;                \
103 };
104
105 #define EVENTHANDLER_INVOKE(name, args...)                              \
106 do {                                                                    \
107     struct eventhandler_list *_el;                                      \
108     struct eventhandler_entry *_ep;                                     \
109                                                                         \
110     if ((_el = eventhandler_find_list(#name)) != NULL) {                \
111         for (_ep = TAILQ_FIRST(&(_el->el_entries));                     \
112              _ep != NULL;                                               \
113              _ep = TAILQ_NEXT(_ep, ee_link)) {                          \
114             ((struct eventhandler_entry_ ## name *)_ep)->eh_func(_ep->ee_arg , ## args); \
115         }                                                               \
116     }                                                                   \
117 } while (0);
118
119 #define EVENTHANDLER_REGISTER(name, func, arg, priority) \
120     eventhandler_register(NULL, #name, func, arg, priority)
121
122 #define EVENTHANDLER_DEREGISTER(name, tag)              \
123 do {                                                    \
124     struct eventhandler_list *_el;                      \
125                                                         \
126     if ((_el = eventhandler_find_list(#name)) != NULL)  \
127         eventhandler_deregister(_el, tag);              \
128 } while(0);
129         
130
131 extern eventhandler_tag eventhandler_register(struct eventhandler_list *list, 
132                                               char *name,
133                                               void *func, 
134                                               void *arg, 
135                                               int priority);
136 extern void             eventhandler_deregister(struct eventhandler_list *list,
137                                                 eventhandler_tag tag);
138 extern struct eventhandler_list *eventhandler_find_list(char *name);
139
140 /*
141  * Standard system event queues.
142  */
143
144 /* Shutdown events */
145 typedef void (*shutdown_fn) __P((void *, int));
146
147 #define SHUTDOWN_PRI_FIRST      0
148 #define SHUTDOWN_PRI_DEFAULT    10000
149 #define SHUTDOWN_PRI_LAST       20000
150
151 EVENTHANDLER_DECLARE(shutdown_pre_sync, shutdown_fn);   /* before fs sync */
152 EVENTHANDLER_DECLARE(shutdown_post_sync, shutdown_fn);  /* after fs sync */
153 EVENTHANDLER_DECLARE(shutdown_final, shutdown_fn);
154
155 #endif /* SYS_EVENTHANDLER_H */