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 #ifndef _SYS_EVENTHANDLER_H_ 30 #define _SYS_EVENTHANDLER_H_ 31 32 #if !defined(_KERNEL) && !defined(_KERNEL_STRUCTURES) 33 34 #error "This file should not be included by userland programs." 35 36 #else 37 38 #include <sys/queue.h> 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 eventhandler_tag eventhandler_register(struct eventhandler_list *, 142 const char *, void *, void *, 143 int); 144 void eventhandler_deregister(struct eventhandler_list *, 145 eventhandler_tag); 146 struct eventhandler_list *eventhandler_find_list(const char *); 147 #endif /* _KERNEL */ 148 149 /* 150 * Standard system event queues. 151 */ 152 153 /* Generic priority levels */ 154 #define EVENTHANDLER_PRI_FIRST 0 155 #define EVENTHANDLER_PRI_ANY 10000 156 #define EVENTHANDLER_PRI_LAST 20000 157 158 struct image_params; 159 struct proc; 160 161 /* Shutdown events */ 162 typedef void (*shutdown_fn) (void *, int); 163 164 #define SHUTDOWN_PRI_FIRST EVENTHANDLER_PRI_FIRST 165 #define SHUTDOWN_PRI_SECOND (EVENTHANDLER_PRI_FIRST + 1) 166 #define SHUTDOWN_PRI_THIRD (EVENTHANDLER_PRI_FIRST + 2) 167 #define SHUTDOWN_PRI_DEFAULT EVENTHANDLER_PRI_ANY 168 #define SHUTDOWN_PRI_DRIVER (EVENTHANDLER_PRI_ANY + 5000) 169 #define SHUTDOWN_PRI_LAST EVENTHANDLER_PRI_LAST 170 typedef void (*execlist_fn)(void *, struct image_params *); 171 typedef void (*exit_list_fn)(void *, struct proc *); 172 173 EVENTHANDLER_DECLARE(shutdown_pre_sync, shutdown_fn); /* before fs sync */ 174 EVENTHANDLER_DECLARE(shutdown_post_sync, shutdown_fn); /* after fs sync */ 175 EVENTHANDLER_DECLARE(shutdown_final, shutdown_fn); 176 177 #endif /* _KERNEL || _KERNEL_STRUCTURES */ 178 #endif /* !_SYS_EVENTHANDLER_H_ */ 179