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