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 #include <sys/queue.h> 30 31 #ifndef _SYS_EVENTHANDLER_H_ 32 #define _SYS_EVENTHANDLER_H_ 33 34 #if !defined(_KERNEL) && !defined(_KERNEL_STRUCTURES) 35 36 #error "This file should not be included by userland programs." 37 38 #else 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 extern eventhandler_tag eventhandler_register(struct eventhandler_list *list, 142 const char *name, 143 void *func, 144 void *arg, 145 int priority); 146 extern void eventhandler_deregister(struct eventhandler_list *list, 147 eventhandler_tag tag); 148 extern struct eventhandler_list *eventhandler_find_list(const char *name); 149 #endif /* _KERNEL */ 150 151 /* 152 * Standard system event queues. 153 */ 154 155 /* Generic priority levels */ 156 #define EVENTHANDLER_PRI_FIRST 0 157 #define EVENTHANDLER_PRI_ANY 10000 158 #define EVENTHANDLER_PRI_LAST 20000 159 160 /* BPF attach/detach events */ 161 struct ifnet; 162 typedef void (*bpf_track_fn)(void *, struct ifnet *, int /* dlt */, 163 int /* 1 =>'s attach */); 164 EVENTHANDLER_DECLARE(bpf_track, bpf_track_fn); 165 166 struct image_params; 167 struct proc; 168 169 /* Shutdown events */ 170 typedef void (*shutdown_fn) (void *, int); 171 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 *); 180 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); 186 187 #endif /* _KERNEL || _KERNEL_STRUCTURES */ 188 #endif /* !_SYS_EVENTHANDLER_H_ */ 189