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