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