2 * Copyright (c) 1999 Michael Smith <msmith@freebsd.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
26 * $FreeBSD: src/sys/sys/eventhandler.h,v 1.5 2000/01/16 06:11:33 bde Exp $
29 #include <sys/queue.h>
31 #ifndef _SYS_EVENTHANDLER_H_
32 #define _SYS_EVENTHANDLER_H_
34 #if !defined(_KERNEL) && !defined(_KERNEL_STRUCTURES)
36 #error "This file should not be included by userland programs."
40 struct eventhandler_entry
42 TAILQ_ENTRY(eventhandler_entry
) ee_link
;
47 struct eventhandler_list
49 TAILQ_ENTRY(eventhandler_list
) el_link
;
52 #define EHE_INITTED (1<<0)
53 TAILQ_HEAD(,eventhandler_entry
) el_entries
;
56 typedef struct eventhandler_entry
*eventhandler_tag
;
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
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.
68 #define EVENTHANDLER_FAST_DECLARE(name, type) \
69 extern struct eventhandler_list Xeventhandler_list_ ## name ; \
70 struct eventhandler_entry_ ## name \
72 struct eventhandler_entry ee; \
77 #define EVENTHANDLER_FAST_DEFINE(name, type) \
78 struct eventhandler_list Xeventhandler_list_ ## name = { #name }; \
81 #define EVENTHANDLER_FAST_INVOKE(name, args...) \
83 struct eventhandler_list *_el = &Xeventhandler_list_ ## name ; \
84 struct eventhandler_entry *_ep = TAILQ_FIRST(&(_el->el_entries)); \
86 while (_ep != NULL) { \
87 ((struct eventhandler_entry_ ## name *)_ep)->eh_func(_ep->ee_arg , ## args); \
88 _ep = TAILQ_NEXT(_ep, ee_link); \
92 #define EVENTHANDLER_FAST_REGISTER(name, func, arg, priority) \
93 eventhandler_register(Xeventhandler_list_ ## name, #name, func, arg, priority)
95 #define EVENTHANDLER_FAST_DEREGISTER(name, tag) \
96 eventhandler_deregister(Xeventhandler_list ## name, tag)
100 * Slow handlers are entirely dynamic; lists are created
101 * when entries are added to them, and thus have no concept of "owner".
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.
106 #define EVENTHANDLER_DECLARE(name, type) \
107 struct eventhandler_entry_ ## name \
109 struct eventhandler_entry ee; \
114 #define EVENTHANDLER_INVOKE(name, args...) \
116 struct eventhandler_list *_el; \
117 struct eventhandler_entry *_ep; \
119 if ((_el = eventhandler_find_list(#name)) != NULL) { \
120 for (_ep = TAILQ_FIRST(&(_el->el_entries)); \
122 _ep = TAILQ_NEXT(_ep, ee_link)) { \
123 ((struct eventhandler_entry_ ## name *)_ep)->eh_func(_ep->ee_arg , ## args); \
128 #define EVENTHANDLER_REGISTER(name, func, arg, priority) \
129 eventhandler_register(NULL, #name, func, arg, priority)
131 #define EVENTHANDLER_DEREGISTER(name, tag) \
133 struct eventhandler_list *_el; \
135 if ((_el = eventhandler_find_list(#name)) != NULL) \
136 eventhandler_deregister(_el, tag); \
141 extern eventhandler_tag
eventhandler_register(struct eventhandler_list
*list
,
146 extern void eventhandler_deregister(struct eventhandler_list
*list
,
147 eventhandler_tag tag
);
148 extern struct eventhandler_list
*eventhandler_find_list(const char *name
);
152 * Standard system event queues.
155 /* Generic priority levels */
156 #define EVENTHANDLER_PRI_FIRST 0
157 #define EVENTHANDLER_PRI_ANY 10000
158 #define EVENTHANDLER_PRI_LAST 20000
160 /* BPF attach/detach events */
162 typedef void (*bpf_track_fn
)(void *, struct ifnet
*, int /* dlt */,
163 int /* 1 =>'s attach */);
164 EVENTHANDLER_DECLARE(bpf_track
, bpf_track_fn
);
169 /* Shutdown events */
170 typedef void (*shutdown_fn
) (void *, int);
172 #define SHUTDOWN_PRI_FIRST EVENTHANDLER_PRI_FIRST
173 #define SHUTDOWN_PRI_SECOND (EVENTHANDLER_PRI_FIRST + 1)
174 #define SHUTDOWN_PRI_THIRD (EVENTHANDLER_PRI_FIRST + 2)
175 #define SHUTDOWN_PRI_DEFAULT EVENTHANDLER_PRI_ANY
176 #define SHUTDOWN_PRI_DRIVER (EVENTHANDLER_PRI_ANY + 5000)
177 #define SHUTDOWN_PRI_LAST EVENTHANDLER_PRI_LAST
178 typedef void (*execlist_fn
)(void *, struct image_params
*);
179 typedef void (*exit_list_fn
)(void *, struct proc
*);
181 EVENTHANDLER_DECLARE(shutdown_pre_sync
, shutdown_fn
); /* before fs sync */
182 EVENTHANDLER_DECLARE(shutdown_post_sync
, shutdown_fn
); /* after fs sync */
183 EVENTHANDLER_DECLARE(shutdown_final
, shutdown_fn
);
184 EVENTHANDLER_DECLARE(process_exec
, execlist_fn
);
185 EVENTHANDLER_DECLARE(process_exit
, exit_list_fn
);
187 #endif /* _KERNEL || _KERNEL_STRUCTURES */
188 #endif /* !_SYS_EVENTHANDLER_H_ */