eventhandler.h revision 50477
150107Smsmith/*- 250107Smsmith * Copyright (c) 1999 Michael Smith <msmith@freebsd.org> 350107Smsmith * All rights reserved. 450107Smsmith * 550107Smsmith * Redistribution and use in source and binary forms, with or without 650107Smsmith * modification, are permitted provided that the following conditions 750107Smsmith * are met: 850107Smsmith * 1. Redistributions of source code must retain the above copyright 950107Smsmith * notice, this list of conditions and the following disclaimer. 1050107Smsmith * 2. Redistributions in binary form must reproduce the above copyright 1150107Smsmith * notice, this list of conditions and the following disclaimer in the 1250107Smsmith * documentation and/or other materials provided with the distribution. 1350107Smsmith * 1450107Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1550107Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1650107Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1750107Smsmith * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1850107Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1950107Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2050107Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2150107Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2250107Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2350107Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2450107Smsmith * SUCH DAMAGE. 2550107Smsmith * 2650477Speter * $FreeBSD: head/sys/sys/eventhandler.h 50477 1999-08-28 01:08:13Z peter $ 2750107Smsmith */ 2850107Smsmith 2950107Smsmith#include <sys/queue.h> 3050107Smsmith 3150107Smsmith#ifndef SYS_EVENTHANDLER_H 3250107Smsmith#define SYS_EVENTHANDLER_H 3350107Smsmith 3450107Smsmithstruct eventhandler_entry 3550107Smsmith{ 3650107Smsmith TAILQ_ENTRY(eventhandler_entry) ee_link; 3750107Smsmith int ee_priority; 3850107Smsmith void *ee_arg; 3950107Smsmith}; 4050107Smsmith 4150107Smsmithstruct eventhandler_list 4250107Smsmith{ 4350107Smsmith TAILQ_ENTRY(eventhandler_list) el_link; 4450107Smsmith char *el_name; 4550107Smsmith int el_flags; 4650107Smsmith#define EHE_INITTED (1<<0) 4750107Smsmith TAILQ_HEAD(,eventhandler_entry) el_entries; 4850107Smsmith}; 4950107Smsmith 5050107Smsmithtypedef struct eventhandler_entry *eventhandler_tag; 5150107Smsmith 5250107Smsmith/* 5350107Smsmith * Fast handler lists require the eventhandler list be present 5450107Smsmith * at link time. They don't allow addition of entries to 5550107Smsmith * unknown eventhandler lists, ie. each list must have an 5650107Smsmith * "owner". 5750107Smsmith * 5850107Smsmith * Fast handler lists must be defined once by the owner 5950107Smsmith * of the eventhandler list, and the declaration must be in 6050107Smsmith * scope at any point the list is manipulated. 6150107Smsmith */ 6250107Smsmith#define EVENTHANDLER_FAST_DECLARE(name, type) \ 6350107Smsmithextern struct eventhandler_list Xeventhandler_list_ ## name ; \ 6450107Smsmithstruct eventhandler_entry_ ## name \ 6550107Smsmith{ \ 6650107Smsmith struct eventhandler_entry ee; \ 6750107Smsmith type eh_func; \ 6850107Smsmith}; 6950107Smsmith 7050107Smsmith#define EVENTHANDLER_FAST_DEFINE(name, type) \ 7150107Smsmithstruct eventhandler_list Xeventhandler_list_ ## name = { #name }; 7250107Smsmith 7350107Smsmith#define EVENTHANDLER_FAST_INVOKE(name, args...) \ 7450107Smsmithdo { \ 7550158Sgreen struct eventhandler_list *_el = &Xeventhandler_list_ ## name ; \ 7650107Smsmith struct eventhandler_entry *_ep = TAILQ_FIRST(&(_el->el_entries)); \ 7750107Smsmith \ 7850107Smsmith while (_ep != NULL) { \ 7950107Smsmith ((struct eventhandler_entry_ ## name *)_ep)->eh_func(_ep->ee_arg , ## args); \ 8050107Smsmith _ep = TAILQ_NEXT(_ep, ee_link); \ 8150107Smsmith } \ 8250107Smsmith} while (0); 8350107Smsmith 8450107Smsmith#define EVENTHANDLER_FAST_REGISTER(name, func, arg, priority) \ 8550107Smsmith eventhandler_register(Xeventhandler_list_ ## name, #name, func, arg, priority) 8650107Smsmith 8750107Smsmith#define EVENTHANDLER_FAST_DEREGISTER(name, tag, func) \ 8850107Smsmith eventhandler_deregister(Xeventhandler_list ## name, tag, func) 8950107Smsmith 9050107Smsmith 9150107Smsmith/* 9250107Smsmith * Slow handlerss are entirely dynamic; lists are created 9350107Smsmith * when entries are added to them, and thus have no concept of "owner", 9450107Smsmith * 9550107Smsmith * Slow handlerss need to be declared, but do not need to be defined. The 9650107Smsmith * declaration must be in scope wherever the handler is to be invoked. 9750107Smsmith */ 9850107Smsmith#define EVENTHANDLER_DECLARE(name, type) \ 9950107Smsmithstruct eventhandler_entry_ ## name \ 10050107Smsmith{ \ 10150107Smsmith struct eventhandler_entry ee; \ 10250107Smsmith type eh_func; \ 10350107Smsmith}; 10450107Smsmith 10550107Smsmith#define EVENTHANDLER_INVOKE(name, args...) \ 10650107Smsmithdo { \ 10750107Smsmith struct eventhandler_list *_el; \ 10850107Smsmith struct eventhandler_entry *_ep; \ 10950107Smsmith \ 11050107Smsmith if ((_el = eventhandler_find_list(#name)) != NULL) { \ 11150107Smsmith for (_ep = TAILQ_FIRST(&(_el->el_entries)); \ 11250107Smsmith _ep != NULL; \ 11350107Smsmith _ep = TAILQ_NEXT(_ep, ee_link)) { \ 11450107Smsmith ((struct eventhandler_entry_ ## name *)_ep)->eh_func(_ep->ee_arg , ## args); \ 11550107Smsmith } \ 11650107Smsmith } \ 11750107Smsmith} while (0); 11850107Smsmith 11950107Smsmith#define EVENTHANDLER_REGISTER(name, func, arg, priority) \ 12050107Smsmith eventhandler_register(NULL, #name, func, arg, priority) 12150107Smsmith 12250107Smsmith#define EVENTHANDLER_DEREGISTER(name, tag, func) \ 12350107Smsmithdo { \ 12450107Smsmith struct eventhandler_list *_el; \ 12550107Smsmith \ 12650107Smsmith if ((_el = eventhandler_find_list(#name)) != NULL) \ 12750107Smsmith eventhandler_deregister(_el, tag, func); \ 12850107Smsmith} while(0); 12950107Smsmith 13050107Smsmith 13150107Smsmithextern eventhandler_tag eventhandler_register(struct eventhandler_list *list, 13250107Smsmith char *name, 13350107Smsmith void *func, 13450107Smsmith void *arg, 13550107Smsmith int priority); 13650107Smsmithextern void eventhandler_deregister(struct eventhandler_list *list, 13750107Smsmith eventhandler_tag tag); 13850107Smsmithextern struct eventhandler_list *eventhandler_find_list(char *name); 13950107Smsmith 14050107Smsmith/* 14150107Smsmith * Standard system event queues. 14250107Smsmith */ 14350107Smsmith 14450107Smsmith/* Shutdown events */ 14550107Smsmithtypedef void (*shutdown_fn) __P((void *, int)); 14650107Smsmith 14750107Smsmith#define SHUTDOWN_PRI_FIRST 0 14850107Smsmith#define SHUTDOWN_PRI_DEFAULT 10000 14950107Smsmith#define SHUTDOWN_PRI_LAST 20000 15050107Smsmith 15150107SmsmithEVENTHANDLER_DECLARE(shutdown_pre_sync, shutdown_fn); /* before fs sync */ 15250107SmsmithEVENTHANDLER_DECLARE(shutdown_post_sync, shutdown_fn); /* after fs sync */ 15350107SmsmithEVENTHANDLER_DECLARE(shutdown_final, shutdown_fn); 15450107Smsmith 15550107Smsmith#endif /* SYS_EVENTHANDLER_H */ 156