xref: /dragonfly/sys/sys/eventhandler.h (revision b5516a553a649d22c5fc69edf6d01122399d2529)
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: src/sys/sys/eventhandler.h,v 1.5 2000/01/16 06:11:33 bde Exp $
27  */
28 
29 #ifndef _SYS_EVENTHANDLER_H_
30 #define _SYS_EVENTHANDLER_H_
31 
32 #if !defined(_KERNEL) && !defined(_KERNEL_STRUCTURES)
33 
34 #error "This file should not be included by userland programs."
35 
36 #else
37 
38 #include <sys/queue.h>
39 
40 struct eventhandler_entry
41 {
42     TAILQ_ENTRY(eventhandler_entry)     ee_link;
43     int                                           ee_priority;
44     void                                *ee_arg;
45 };
46 
47 struct eventhandler_list
48 {
49     TAILQ_ENTRY(eventhandler_list)      el_link;
50     char                                *el_name;
51     int                                           el_flags;
52 #define EHE_INITTED (1<<0)
53     TAILQ_HEAD(,eventhandler_entry)     el_entries;
54 };
55 
56 typedef struct eventhandler_entry       *eventhandler_tag;
57 
58 /*
59  * Fast handler lists require the eventhandler list be present
60  * at link time.  They don't allow addition of entries to
61  * unknown eventhandler lists, ie. each list must have an
62  * "owner".
63  *
64  * Fast handler lists must be defined once by the owner
65  * of the eventhandler list, and the declaration must be in
66  * scope at any point the list is manipulated.
67  */
68 #define EVENTHANDLER_FAST_DECLARE(name, type)                         \
69 extern struct eventhandler_list Xeventhandler_list_ ## name ;         \
70 struct eventhandler_entry_ ## name                                    \
71 {                                                                               \
72     struct eventhandler_entry ee;                                     \
73     type            eh_func;                                \
74 };                                                                              \
75 struct __hack
76 
77 #define EVENTHANDLER_FAST_DEFINE(name, type)                                    \
78 struct eventhandler_list Xeventhandler_list_ ## name = { #name };     \
79 struct __hack
80 
81 #define EVENTHANDLER_FAST_INVOKE(name, args...)                                 \
82 do {                                                                                      \
83     struct eventhandler_list *_el = &Xeventhandler_list_ ## name ;    \
84     struct eventhandler_entry *_ep = TAILQ_FIRST(&(_el->el_entries)); \
85                                                                                           \
86     while (_ep != NULL) {                                                       \
87           ((struct eventhandler_entry_ ## name *)_ep)->eh_func(_ep->ee_arg , ## args); \
88           _ep = TAILQ_NEXT(_ep, ee_link);                                                 \
89     }                                                                                     \
90 } while (0)
91 
92 #define EVENTHANDLER_FAST_REGISTER(name, func, arg, priority) \
93     eventhandler_register(Xeventhandler_list_ ## name, #name, func, arg, priority)
94 
95 #define EVENTHANDLER_FAST_DEREGISTER(name, tag) \
96     eventhandler_deregister(Xeventhandler_list ## name, tag)
97 
98 
99 /*
100  * Slow handlers are entirely dynamic; lists are created
101  * when entries are added to them, and thus have no concept of "owner".
102  *
103  * Slow handlers need to be declared, but do not need to be defined. The
104  * declaration must be in scope wherever the handler is to be invoked.
105  */
106 #define EVENTHANDLER_DECLARE(name, type)          \
107 struct eventhandler_entry_ ## name                \
108 {                                                           \
109     struct eventhandler_entry ee;                 \
110     type            eh_func;            \
111 };                                                          \
112 struct __hack
113 
114 #define EVENTHANDLER_INVOKE(name, args...)                                      \
115 do {                                                                                      \
116     struct eventhandler_list *_el;                                              \
117     struct eventhandler_entry *_ep;                                             \
118                                                                                           \
119     if ((_el = eventhandler_find_list(#name)) != NULL) {              \
120           for (_ep = TAILQ_FIRST(&(_el->el_entries));                           \
121                _ep != NULL;                                                     \
122                _ep = TAILQ_NEXT(_ep, ee_link)) {                                \
123               ((struct eventhandler_entry_ ## name *)_ep)->eh_func(_ep->ee_arg , ## args); \
124           }                                                                               \
125     }                                                                                     \
126 } while (0)
127 
128 #define EVENTHANDLER_REGISTER(name, func, arg, priority) \
129     eventhandler_register(NULL, #name, func, arg, priority)
130 
131 #define EVENTHANDLER_DEREGISTER(name, tag)                  \
132 do {                                                                  \
133     struct eventhandler_list *_el;                          \
134                                                                       \
135     if ((_el = eventhandler_find_list(#name)) != NULL)      \
136           eventhandler_deregister(_el, tag);                \
137 } while(0)
138 
139 
140 #ifdef _KERNEL
141 eventhandler_tag    eventhandler_register(struct eventhandler_list *,
142                                                         const char *, void *, void *,
143                                                         int);
144 void                          eventhandler_deregister(struct eventhandler_list *,
145                                                             eventhandler_tag);
146 struct eventhandler_list *eventhandler_find_list(const char *);
147 #endif /* _KERNEL */
148 
149 /*
150  * Standard system event queues.
151  */
152 
153 /* Generic priority levels */
154 #define   EVENTHANDLER_PRI_FIRST        0
155 #define   EVENTHANDLER_PRI_ANY          10000
156 #define   EVENTHANDLER_PRI_LAST         20000
157 
158 struct image_params;
159 struct proc;
160 
161 /* Shutdown events */
162 typedef void (*shutdown_fn) (void *, int);
163 
164 #define   SHUTDOWN_PRI_FIRST  EVENTHANDLER_PRI_FIRST
165 #define   SHUTDOWN_PRI_SECOND (EVENTHANDLER_PRI_FIRST + 1)
166 #define   SHUTDOWN_PRI_THIRD  (EVENTHANDLER_PRI_FIRST + 2)
167 #define   SHUTDOWN_PRI_DEFAULT          EVENTHANDLER_PRI_ANY
168 #define   SHUTDOWN_PRI_DRIVER (EVENTHANDLER_PRI_ANY + 5000)
169 #define   SHUTDOWN_PRI_LAST   EVENTHANDLER_PRI_LAST
170 typedef void (*execlist_fn)(void *, struct image_params *);
171 typedef void (*exit_list_fn)(void *, struct proc *);
172 
173 EVENTHANDLER_DECLARE(shutdown_pre_sync, shutdown_fn);       /* before fs sync */
174 EVENTHANDLER_DECLARE(shutdown_post_sync, shutdown_fn);      /* after fs sync */
175 EVENTHANDLER_DECLARE(shutdown_final, shutdown_fn);
176 
177 #endif    /* _KERNEL || _KERNEL_STRUCTURES */
178 #endif    /* !_SYS_EVENTHANDLER_H_ */
179