]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/sys/eventhandler.h
This patch adds the "LOCKSHARED" option to namei which causes it to only acquire...
[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 #ifndef SYS_EVENTHANDLER_H
30 #define SYS_EVENTHANDLER_H
31
32 /*
33  * XXX - compatability until lockmgr() goes away or all the #includes are
34  * updated.
35  */
36 #include <sys/lockmgr.h>
37
38 #include <sys/queue.h>
39 #include <sys/_lock.h>
40 #include <sys/_mutex.h>
41
42 struct eventhandler_entry 
43 {
44     TAILQ_ENTRY(eventhandler_entry)     ee_link;
45     int                                 ee_priority;
46     void                                *ee_arg;
47 };
48
49 struct eventhandler_list 
50 {
51     char                                *el_name;
52     int                                 el_flags;
53 #define EHE_INITTED     (1<<0)
54     struct lock                         el_lock;
55     TAILQ_ENTRY(eventhandler_list)      el_link;
56     TAILQ_HEAD(,eventhandler_entry)     el_entries;
57 };
58
59 typedef struct eventhandler_entry       *eventhandler_tag;
60
61 /* 
62  * Fast handler lists require the eventhandler list be present
63  * at link time.  They don't allow addition of entries to
64  * unknown eventhandler lists, ie. each list must have an 
65  * "owner".
66  *
67  * Fast handler lists must be defined once by the owner 
68  * of the eventhandler list, and the declaration must be in 
69  * scope at any point the list is manipulated.
70  */
71 #define EVENTHANDLER_FAST_DECLARE(name, type)                   \
72 extern struct eventhandler_list Xeventhandler_list_ ## name ;   \
73 struct eventhandler_entry_ ## name                              \
74 {                                                               \
75     struct eventhandler_entry   ee;                             \
76     type                eh_func;                                \
77 };                                                              \
78 struct __hack
79
80 #define EVENTHANDLER_FAST_DEFINE(name, type)                            \
81 struct eventhandler_list Xeventhandler_list_ ## name = { #name };       \
82 struct __hack
83
84 #define EVENTHANDLER_FAST_INVOKE(name, args...)                                 \
85 do {                                                                            \
86     struct eventhandler_list *_el = &Xeventhandler_list_ ## name ;              \
87     struct eventhandler_entry *_ep, *_en;                                       \
88                                                                                 \
89     if (_el->el_flags & EHE_INITTED) {                                          \
90         lockmgr(&_el->el_lock, LK_EXCLUSIVE, NULL, curthread);                  \
91         _ep = TAILQ_FIRST(&(_el->el_entries));                                  \
92         while (_ep != NULL) {                                                   \
93             _en = TAILQ_NEXT(_ep, ee_link);                                     \
94             ((struct eventhandler_entry_ ## name *)_ep)->eh_func(_ep->ee_arg ,  \
95                                                                  ## args);      \
96             _ep = _en;                                                          \
97         }                                                                       \
98         lockmgr(&_el->el_lock, LK_RELEASE, NULL, curthread);                    \
99     }                                                                           \
100 } while (0)
101
102 #define EVENTHANDLER_FAST_REGISTER(name, func, arg, priority) \
103     eventhandler_register(&Xeventhandler_list_ ## name, #name, func, arg, priority)
104
105 #define EVENTHANDLER_FAST_DEREGISTER(name, tag) \
106     eventhandler_deregister(&Xeventhandler_list_ ## name, tag)
107
108 /*
109  * Slow handlers are entirely dynamic; lists are created
110  * when entries are added to them, and thus have no concept of "owner",
111  *
112  * Slow handlers need to be declared, but do not need to be defined. The
113  * declaration must be in scope wherever the handler is to be invoked.
114  */
115 #define EVENTHANDLER_DECLARE(name, type)        \
116 struct eventhandler_entry_ ## name              \
117 {                                               \
118     struct eventhandler_entry   ee;             \
119     type                eh_func;                \
120 };                                              \
121 struct __hack
122
123 #define EVENTHANDLER_INVOKE(name, args...)                                      \
124 do {                                                                            \
125     struct eventhandler_list *_el;                                              \
126     struct eventhandler_entry *_ep, *_en;                                       \
127                                                                                 \
128     if (((_el = eventhandler_find_list(#name)) != NULL) &&                      \
129         (_el->el_flags & EHE_INITTED)) {                                        \
130         lockmgr(&_el->el_lock, LK_EXCLUSIVE, NULL, curthread);                  \
131         _ep = TAILQ_FIRST(&(_el->el_entries));                                  \
132         while (_ep != NULL) {                                                   \
133             _en = TAILQ_NEXT(_ep, ee_link);                                     \
134             ((struct eventhandler_entry_ ## name *)_ep)->eh_func(_ep->ee_arg ,  \
135                                                                  ## args);      \
136             _ep = _en;                                                          \
137         }                                                                       \
138         lockmgr(&_el->el_lock, LK_RELEASE, NULL, curthread);                    \
139     }                                                                           \
140 } while (0)
141
142 #define EVENTHANDLER_REGISTER(name, func, arg, priority) \
143     eventhandler_register(NULL, #name, func, arg, priority)
144
145 #define EVENTHANDLER_DEREGISTER(name, tag)              \
146 do {                                                    \
147     struct eventhandler_list *_el;                      \
148                                                         \
149     if ((_el = eventhandler_find_list(#name)) != NULL)  \
150         eventhandler_deregister(_el, tag);              \
151 } while(0)
152         
153
154 extern eventhandler_tag eventhandler_register(struct eventhandler_list *list, 
155                                               char *name,
156                                               void *func, 
157                                               void *arg, 
158                                               int priority);
159 extern void             eventhandler_deregister(struct eventhandler_list *list,
160                                                 eventhandler_tag tag);
161 extern struct eventhandler_list *eventhandler_find_list(char *name);
162
163 /*
164  * Standard system event queues.
165  */
166
167 /* Shutdown events */
168 typedef void (*shutdown_fn) __P((void *, int));
169
170 #define SHUTDOWN_PRI_FIRST      0
171 #define SHUTDOWN_PRI_DEFAULT    10000
172 #define SHUTDOWN_PRI_LAST       20000
173
174 EVENTHANDLER_DECLARE(shutdown_pre_sync, shutdown_fn);   /* before fs sync */
175 EVENTHANDLER_DECLARE(shutdown_post_sync, shutdown_fn);  /* after fs sync */
176 EVENTHANDLER_DECLARE(shutdown_final, shutdown_fn);
177
178 /* Idle process event */
179 typedef void (*idle_eventhandler_t) __P((void *, int));
180
181 #define IDLE_PRI_FIRST          10000
182 #define IDLE_PRI_LAST           20000
183 EVENTHANDLER_FAST_DECLARE(idle_event, idle_eventhandler_t);
184
185
186 #endif /* SYS_EVENTHANDLER_H */