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