diff options
-rw-r--r-- | sys/fs/pseudofs/pseudofs_vncache.c | 12 | ||||
-rw-r--r-- | sys/kern/kern_exec.c | 61 | ||||
-rw-r--r-- | sys/kern/kern_exit.c | 67 | ||||
-rw-r--r-- | sys/kern/kern_fork.c | 88 | ||||
-rw-r--r-- | sys/kern/sysv_sem.c | 12 | ||||
-rw-r--r-- | sys/kern/uipc_sem.c | 18 | ||||
-rw-r--r-- | sys/kern/vfs_aio.c | 17 | ||||
-rw-r--r-- | sys/netncp/ncp_subr.c | 14 | ||||
-rw-r--r-- | sys/sys/eventhandler.h | 11 | ||||
-rw-r--r-- | sys/sys/systm.h | 18 |
10 files changed, 62 insertions, 256 deletions
diff --git a/sys/fs/pseudofs/pseudofs_vncache.c b/sys/fs/pseudofs/pseudofs_vncache.c index c832925..2dc94fe 100644 --- a/sys/fs/pseudofs/pseudofs_vncache.c +++ b/sys/fs/pseudofs/pseudofs_vncache.c @@ -31,6 +31,7 @@ #include <sys/param.h> #include <sys/kernel.h> #include <sys/systm.h> +#include <sys/eventhandler.h> #include <sys/lock.h> #include <sys/malloc.h> #include <sys/mutex.h> @@ -45,7 +46,8 @@ static MALLOC_DEFINE(M_PFSVNCACHE, "pfs_vncache", "pseudofs vnode cache"); static struct mtx pfs_vncache_mutex; static struct pfs_vdata *pfs_vncache; -static void pfs_exit(struct proc *p); +static eventhandler_tag pfs_exit_tag; +static void pfs_exit(void *arg, struct proc *p); SYSCTL_NODE(_vfs_pfs, OID_AUTO, vncache, CTLFLAG_RW, 0, "pseudofs vnode cache"); @@ -80,8 +82,8 @@ pfs_vncache_load(void) { mtx_init(&pfs_vncache_mutex, "pseudofs_vncache", NULL, MTX_DEF | MTX_RECURSE); - /* XXX at_exit() can fail with ENOMEN */ - at_exit(pfs_exit); + pfs_exit_tag = EVENTHANDLER_REGISTER(process_exit, pfs_exit, NULL, + EVENTHANDLER_PRI_ANY); } /* @@ -90,7 +92,7 @@ pfs_vncache_load(void) void pfs_vncache_unload(void) { - rm_at_exit(pfs_exit); + EVENTHANDLER_DEREGISTER(process_exit, pfs_exit_tag); if (pfs_vncache_entries != 0) printf("pfs_vncache_unload(): %d entries remaining\n", pfs_vncache_entries); @@ -218,7 +220,7 @@ pfs_vncache_free(struct vnode *vp) * Free all vnodes associated with a defunct process */ static void -pfs_exit(struct proc *p) +pfs_exit(void *arg, struct proc *p) { struct pfs_vdata *pvd, *prev; diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index a359b75..a8c668b 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -31,6 +31,7 @@ #include <sys/param.h> #include <sys/systm.h> +#include <sys/eventhandler.h> #include <sys/lock.h> #include <sys/mutex.h> #include <sys/sysproto.h> @@ -72,25 +73,12 @@ MALLOC_DEFINE(M_PARGS, "proc-args", "Process arguments"); -static MALLOC_DEFINE(M_ATEXEC, "atexec", "atexec callback"); - static int sysctl_kern_ps_strings(SYSCTL_HANDLER_ARGS); static int sysctl_kern_usrstack(SYSCTL_HANDLER_ARGS); static int sysctl_kern_stackprot(SYSCTL_HANDLER_ARGS); static int kern_execve(struct thread *td, char *fname, char **argv, char **envv, struct mac *mac_p); -/* - * callout list for things to do at exec time - */ -struct execlist { - execlist_fn function; - TAILQ_ENTRY(execlist) next; -}; - -TAILQ_HEAD(exec_list_head, execlist); -static struct exec_list_head exec_list = TAILQ_HEAD_INITIALIZER(exec_list); - /* XXX This should be vm_size_t. */ SYSCTL_PROC(_kern, KERN_PS_STRINGS, ps_strings, CTLTYPE_ULONG|CTLFLAG_RD, NULL, 0, sysctl_kern_ps_strings, "LU", ""); @@ -840,7 +828,6 @@ exec_new_vmspace(imgp, sv) struct sysentvec *sv; { int error; - struct execlist *ep; struct proc *p = imgp->proc; struct vmspace *vmspace = p->p_vmspace; vm_offset_t stack_addr; @@ -852,11 +839,7 @@ exec_new_vmspace(imgp, sv) imgp->vmspace_destroyed = 1; - /* - * Perform functions registered with at_exec(). - */ - TAILQ_FOREACH(ep, &exec_list, next) - (*ep->function)(p); + EVENTHANDLER_INVOKE(process_exec, p); /* * Blow away entire process VM, if address space not shared, @@ -1223,43 +1206,3 @@ exec_unregister(execsw_arg) execsw = newexecsw; return (0); } - -int -at_exec(function) - execlist_fn function; -{ - struct execlist *ep; - -#ifdef INVARIANTS - /* Be noisy if the programmer has lost track of things */ - if (rm_at_exec(function)) - printf("WARNING: exec callout entry (%p) already present\n", - function); -#endif - ep = malloc(sizeof(*ep), M_ATEXEC, M_NOWAIT); - if (ep == NULL) - return (ENOMEM); - ep->function = function; - TAILQ_INSERT_TAIL(&exec_list, ep, next); - return (0); -} - -/* - * Scan the exec callout list for the given item and remove it. - * Returns the number of items removed (0 or 1) - */ -int -rm_at_exec(function) - execlist_fn function; -{ - struct execlist *ep; - - TAILQ_FOREACH(ep, &exec_list, next) { - if (ep->function == function) { - TAILQ_REMOVE(&exec_list, ep, next); - free(ep, M_ATEXEC); - return (1); - } - } - return (0); -} diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 38af794..c6cb858 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -46,6 +46,7 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/sysproto.h> +#include <sys/eventhandler.h> #include <sys/kernel.h> #include <sys/malloc.h> #include <sys/lock.h> @@ -83,22 +84,9 @@ /* Required to be non-static for SysVR4 emulator */ MALLOC_DEFINE(M_ZOMBIE, "zombie", "zombie proc status"); -static MALLOC_DEFINE(M_ATEXIT, "atexit", "atexit callback"); - static int wait1(struct thread *, struct wait_args *, int); /* - * callout list for things to do at exit time - */ -struct exitlist { - exitlist_fn function; - TAILQ_ENTRY(exitlist) next; -}; - -TAILQ_HEAD(exit_list_head, exitlist); -static struct exit_list_head exit_list = TAILQ_HEAD_INITIALIZER(exit_list); - -/* * exit -- * Death of process. * @@ -121,7 +109,6 @@ sys_exit(struct thread *td, struct sys_exit_args *uap) void exit1(struct thread *td, int rv) { - struct exitlist *ep; struct proc *p, *nq, *q; struct tty *tp; struct vnode *ttyvp; @@ -218,9 +205,7 @@ exit1(struct thread *td, int rv) * e.g. SYSV IPC stuff * XXX what if one of these generates an error? */ - TAILQ_FOREACH(ep, &exit_list, next) - (*ep->function)(p); - + EVENTHANDLER_INVOKE(process_exit, p); MALLOC(p->p_ru, struct rusage *, sizeof(struct rusage), M_ZOMBIE, M_WAITOK); @@ -798,51 +783,3 @@ proc_reparent(struct proc *child, struct proc *parent) LIST_INSERT_HEAD(&parent->p_children, child, p_sibling); child->p_pptr = parent; } - -/* - * The next two functions are to handle adding/deleting items on the - * exit callout list - * - * at_exit(): - * Take the arguments given and put them onto the exit callout list, - * However first make sure that it's not already there. - * returns 0 on success. - */ - -int -at_exit(exitlist_fn function) -{ - struct exitlist *ep; - -#ifdef INVARIANTS - /* Be noisy if the programmer has lost track of things */ - if (rm_at_exit(function)) - printf("WARNING: exit callout entry (%p) already present\n", - function); -#endif - ep = malloc(sizeof(*ep), M_ATEXIT, M_NOWAIT); - if (ep == NULL) - return (ENOMEM); - ep->function = function; - TAILQ_INSERT_TAIL(&exit_list, ep, next); - return (0); -} - -/* - * Scan the exit callout list for the given item and remove it. - * Returns the number of items removed (0 or 1) - */ -int -rm_at_exit(exitlist_fn function) -{ - struct exitlist *ep; - - TAILQ_FOREACH(ep, &exit_list, next) { - if (ep->function == function) { - TAILQ_REMOVE(&exit_list, ep, next); - free(ep, M_ATEXIT); - return (1); - } - } - return (0); -} diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 0c24cc6..11a94d9 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -45,6 +45,7 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/sysproto.h> +#include <sys/eventhandler.h> #include <sys/filedesc.h> #include <sys/kernel.h> #include <sys/sysctl.h> @@ -76,22 +77,6 @@ #include <sys/user.h> #include <machine/critical.h> -static MALLOC_DEFINE(M_ATFORK, "atfork", "atfork callback"); - -/* - * These are the stuctures used to create a callout list for things to do - * when forking a process - */ -struct forklist { - forklist_fn function; - TAILQ_ENTRY(forklist) next; -}; - -static struct sx fork_list_lock; - -TAILQ_HEAD(forklist_head, forklist); -static struct forklist_head fork_list = TAILQ_HEAD_INITIALIZER(fork_list); - #ifndef _SYS_SYSPROTO_H_ struct fork_args { int dummy; @@ -100,14 +85,6 @@ struct fork_args { int forksleep; /* Place for fork1() to sleep on. */ -static void -init_fork_list(void *data __unused) -{ - - sx_init(&fork_list_lock, "fork list"); -} -SYSINIT(fork_list, SI_SUB_INTRINSIC, SI_ORDER_ANY, init_fork_list, NULL); - /* * MPSAFE */ @@ -237,7 +214,6 @@ fork1(td, flags, pages, procp) int trypid; int ok; static int pidchecked = 0; - struct forklist *ep; struct filedesc *fd; struct proc *p1 = td->td_proc; struct thread *td2; @@ -703,11 +679,7 @@ again: * to adjust anything. * What if they have an error? XXX */ - sx_slock(&fork_list_lock); - TAILQ_FOREACH(ep, &fork_list, next) { - (*ep->function)(p1, p2, flags); - } - sx_sunlock(&fork_list_lock); + EVENTHANDLER_INVOKE(process_fork, p1, p2, flags); /* * If RFSTOPPED not requested, make child runnable and add to @@ -772,62 +744,6 @@ fail: } /* - * The next two functionms are general routines to handle adding/deleting - * items on the fork callout list. - * - * at_fork(): - * Take the arguments given and put them onto the fork callout list, - * However first make sure that it's not already there. - * Returns 0 on success or a standard error number. - */ - -int -at_fork(function) - forklist_fn function; -{ - struct forklist *ep; - -#ifdef INVARIANTS - /* let the programmer know if he's been stupid */ - if (rm_at_fork(function)) - printf("WARNING: fork callout entry (%p) already present\n", - function); -#endif - ep = malloc(sizeof(*ep), M_ATFORK, M_NOWAIT); - if (ep == NULL) - return (ENOMEM); - ep->function = function; - sx_xlock(&fork_list_lock); - TAILQ_INSERT_TAIL(&fork_list, ep, next); - sx_xunlock(&fork_list_lock); - return (0); -} - -/* - * Scan the exit callout list for the given item and remove it.. - * Returns the number of items removed (0 or 1) - */ - -int -rm_at_fork(function) - forklist_fn function; -{ - struct forklist *ep; - - sx_xlock(&fork_list_lock); - TAILQ_FOREACH(ep, &fork_list, next) { - if (ep->function == function) { - TAILQ_REMOVE(&fork_list, ep, next); - sx_xunlock(&fork_list_lock); - free(ep, M_ATFORK); - return(1); - } - } - sx_xunlock(&fork_list_lock); - return (0); -} - -/* * Handle the return of a child process from fork1(). This function * is called from the MD fork_trampoline() entry point. */ diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c index 7eeb625..bf1eae3 100644 --- a/sys/kern/sysv_sem.c +++ b/sys/kern/sysv_sem.c @@ -13,6 +13,7 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/sysproto.h> +#include <sys/eventhandler.h> #include <sys/kernel.h> #include <sys/proc.h> #include <sys/lock.h> @@ -35,7 +36,7 @@ static MALLOC_DEFINE(M_SEM, "sem", "SVID compatible semaphores"); static void seminit(void); static int sysvsem_modload(struct module *, int, void *); static int semunload(void); -static void semexit_myhook(struct proc *p); +static void semexit_myhook(void *arg, struct proc *p); static int sysctl_sema(SYSCTL_HANDLER_ARGS); static int semvalid(int semid, struct semid_ds *semaptr); @@ -66,6 +67,7 @@ static struct mtx *sema_mtx; /* semaphore id pool mutexes*/ static struct sem *sem; /* semaphore pool */ SLIST_HEAD(, sem_undo) semu_list; /* list of active undo structures */ static int *semu; /* undo structure pool */ +static eventhandler_tag semexit_tag; #define SEMUNDO_MTX sem_mtx #define SEMUNDO_LOCK() mtx_lock(&SEMUNDO_MTX); @@ -203,8 +205,9 @@ seminit(void) suptr->un_proc = NULL; } SLIST_INIT(&semu_list); - at_exit(semexit_myhook); mtx_init(&sem_mtx, "sem", NULL, MTX_DEF); + semexit_tag = EVENTHANDLER_REGISTER(process_exit, semexit_myhook, NULL, + EVENTHANDLER_PRI_ANY); } static int @@ -215,10 +218,10 @@ semunload(void) if (semtot != 0) return (EBUSY); + EVENTHANDLER_DEREGISTER(process_exit, semexit_tag); free(sem, M_SEM); free(sema, M_SEM); free(semu, M_SEM); - rm_at_exit(semexit_myhook); for (i = 0; i < seminfo.semmni; i++) mtx_destroy(&sema_mtx[i]); mtx_destroy(&sem_mtx); @@ -1139,7 +1142,8 @@ done2: * semaphores. */ static void -semexit_myhook(p) +semexit_myhook(arg, p) + void *arg; struct proc *p; { struct sem_undo *suptr; diff --git a/sys/kern/uipc_sem.c b/sys/kern/uipc_sem.c index 538ff67..9f59626 100644 --- a/sys/kern/uipc_sem.c +++ b/sys/kern/uipc_sem.c @@ -31,6 +31,7 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/sysproto.h> +#include <sys/eventhandler.h> #include <sys/kernel.h> #include <sys/proc.h> #include <sys/lock.h> @@ -57,7 +58,7 @@ static void sem_free(struct ksem *ksnew); static int sem_perm(struct thread *td, struct ksem *ks); static void sem_enter(struct proc *p, struct ksem *ks); static int sem_leave(struct proc *p, struct ksem *ks); -static void sem_exithook(struct proc *p); +static void sem_exithook(void *arg, struct proc *p); static int sem_hasopen(struct thread *td, struct ksem *ks); static int kern_sem_close(struct thread *td, semid_t id); @@ -114,6 +115,8 @@ static int nsems = 0; SYSCTL_DECL(_p1003_1b); SYSCTL_INT(_p1003_1b, OID_AUTO, nsems, CTLFLAG_RD, &nsems, 0, ""); +static eventhandler_tag sem_exit_tag, sem_exec_tag; + #ifdef SEM_DEBUG #define DP(x) printf x #else @@ -769,7 +772,8 @@ err: } static void -sem_exithook(p) +sem_exithook(arg, p) + void *arg; struct proc *p; { struct ksem *ks, *ksnext; @@ -800,16 +804,18 @@ sem_modload(struct module *module, int cmd, void *arg) mtx_init(&sem_lock, "sem", "semaphore", MTX_DEF); p31b_setcfg(CTL_P1003_1B_SEM_NSEMS_MAX, SEM_MAX); p31b_setcfg(CTL_P1003_1B_SEM_VALUE_MAX, SEM_VALUE_MAX); - at_exec(&sem_exithook); - at_exit(&sem_exithook); + sem_exit_tag = EVENTHANDLER_REGISTER(process_exit, sem_exithook, + NULL, EVENTHANDLER_PRI_ANY); + sem_exec_tag = EVENTHANDLER_REGISTER(process_exec, sem_exithook, + NULL, EVENTHANDLER_PRI_ANY); break; case MOD_UNLOAD: if (nsems != 0) { error = EOPNOTSUPP; break; } - rm_at_exit(&sem_exithook); - rm_at_exec(&sem_exithook); + EVENTHANDLER_DEREGISTER(process_exit, sem_exit_tag); + EVENTHANDLER_DEREGISTER(process_exec, sem_exec_tag); mtx_destroy(&sem_lock); break; case MOD_SHUTDOWN: diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c index 9532ff2..c014162 100644 --- a/sys/kern/vfs_aio.c +++ b/sys/kern/vfs_aio.c @@ -25,6 +25,7 @@ #include <sys/malloc.h> #include <sys/bio.h> #include <sys/buf.h> +#include <sys/eventhandler.h> #include <sys/sysproto.h> #include <sys/filedesc.h> #include <sys/kernel.h> @@ -253,7 +254,7 @@ static void aio_process(struct aiocblist *aiocbe); static int aio_newproc(void); static int aio_aqueue(struct thread *td, struct aiocb *job, int type); static void aio_physwakeup(struct buf *bp); -static void aio_proc_rundown(struct proc *p); +static void aio_proc_rundown(void *arg, struct proc *p); static int aio_fphysio(struct aiocblist *aiocbe); static int aio_qphysio(struct proc *p, struct aiocblist *iocb); static void aio_daemon(void *uproc); @@ -278,6 +279,8 @@ static uma_zone_t kaio_zone, aiop_zone, aiocb_zone, aiol_zone, aiolio_zone; static struct filterops aio_filtops = { 0, filt_aioattach, filt_aiodetach, filt_aio }; +static eventhandler_tag exit_tag, exec_tag; + /* * Main operations function for use as a kernel module. */ @@ -330,8 +333,10 @@ aio_onceonly(void) /* XXX: should probably just use so->callback */ aio_swake = &aio_swake_cb; - at_exit(aio_proc_rundown); - at_exec(aio_proc_rundown); + exit_tag = EVENTHANDLER_REGISTER(process_exit, aio_proc_rundown, NULL, + EVENTHANDLER_PRI_ANY); + exec_tag = EVENTHANDLER_REGISTER(process_exec, aio_proc_rundown, NULL, + EVENTHANDLER_PRI_ANY); kqueue_add_filteropts(EVFILT_AIO, &aio_filtops); TAILQ_INIT(&aio_freeproc); TAILQ_INIT(&aio_activeproc); @@ -373,8 +378,8 @@ aio_unload(void) async_io_version = 0; aio_swake = NULL; - rm_at_exit(aio_proc_rundown); - rm_at_exec(aio_proc_rundown); + EVENTHANDLER_DEREGISTER(process_exit, exit_tag); + EVENTHANDLER_DEREGISTER(process_exec, exec_tag); kqueue_del_filteropts(EVFILT_AIO); p31b_setcfg(CTL_P1003_1B_AIO_LISTIO_MAX, -1); p31b_setcfg(CTL_P1003_1B_AIO_MAX, -1); @@ -525,7 +530,7 @@ aio_free_entry(struct aiocblist *aiocbe) * Rundown the jobs for a given process. */ static void -aio_proc_rundown(struct proc *p) +aio_proc_rundown(void *arg, struct proc *p) { int s; struct kaioinfo *ki; diff --git a/sys/netncp/ncp_subr.c b/sys/netncp/ncp_subr.c index e24098a..ea201c4 100644 --- a/sys/netncp/ncp_subr.c +++ b/sys/netncp/ncp_subr.c @@ -34,6 +34,7 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/errno.h> +#include <sys/eventhandler.h> #include <sys/kernel.h> #include <sys/lock.h> #include <sys/malloc.h> @@ -52,8 +53,9 @@ int ncp_debuglevel = 0; struct callout_handle ncp_timer_handle; +static eventhandler_tag ncp_exit_tag; -static void ncp_at_exit(struct proc *p); +static void ncp_at_exit(void *arg, struct proc *p); static void ncp_timer(void *arg); /* @@ -76,7 +78,7 @@ ncp_str_dup(char *s) { void -ncp_at_exit(struct proc *p) +ncp_at_exit(void *arg, struct proc *p) { struct ncp_conn *ncp, *nncp; struct thread *td; @@ -102,10 +104,8 @@ int ncp_init(void) { ncp_conn_init(); - if (at_exit(ncp_at_exit)) { - NCPFATAL("can't register at_exit handler\n"); - return ENOMEM; - } + ncp_exit_tag = EVENTHANDLER_REGISTER(process_exit, ncp_at_exit, NULL, + EVENTHANDLER_PRI_ANY); ncp_timer_handle = timeout(ncp_timer, NULL, NCP_TIMER_TICK); return 0; } @@ -119,7 +119,7 @@ ncp_done(void) if (error) return error; untimeout(ncp_timer, NULL, ncp_timer_handle); - rm_at_exit(ncp_at_exit); + EVENTHANDLER_DEREGISTER(process_exit, ncp_exit_tag); return 0; } diff --git a/sys/sys/eventhandler.h b/sys/sys/eventhandler.h index 4675899..ba9c3f0 100644 --- a/sys/sys/eventhandler.h +++ b/sys/sys/eventhandler.h @@ -208,4 +208,15 @@ typedef void (*vm_lowmem_handler_t)(void *, int); #define LOWMEM_PRI_DEFAULT EVENTHANDLER_PRI_FIRST EVENTHANDLER_DECLARE(vm_lowmem, vm_lowmem_handler_t); +/* Process events */ +struct proc; + +typedef void (*exitlist_fn)(void *, struct proc *); +typedef void (*forklist_fn)(void *, struct proc *, struct proc *, int); +typedef void (*execlist_fn)(void *, struct proc *); + +EVENTHANDLER_DECLARE(process_exit, exitlist_fn); +EVENTHANDLER_DECLARE(process_fork, forklist_fn); +EVENTHANDLER_DECLARE(process_exec, execlist_fn); + #endif /* SYS_EVENTHANDLER_H */ diff --git a/sys/sys/systm.h b/sys/sys/systm.h index 6295921..5443d01 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -283,24 +283,6 @@ static __inline void splx(intrmask_t ipl __unused) { return; } * Various callout lists. */ -/* Exit callout list declarations. */ -typedef void (*exitlist_fn)(struct proc *procp); - -int at_exit(exitlist_fn function); -int rm_at_exit(exitlist_fn function); - -/* Fork callout list declarations. */ -typedef void (*forklist_fn)(struct proc *parent, struct proc *child, int flags); - -int at_fork(forklist_fn function); -int rm_at_fork(forklist_fn function); - -/* Exec callout list declarations. */ -typedef void (*execlist_fn)(struct proc *procp); - -int at_exec(execlist_fn function); -int rm_at_exec(execlist_fn function); - /* * Not exactly a callout LIST, but a callout entry. * Allow an external module to define a hardware watchdog tickler. |