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