diff options
author | jhb <jhb@FreeBSD.org> | 2003-03-24 21:15:35 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2003-03-24 21:15:35 +0000 |
commit | 98a481610a9dcb442e9c2e851c6ef2a330027e45 (patch) | |
tree | 41fad1aa97bccfd68308cf8a8ff0de8b8f243493 /sys/kern | |
parent | 01298a9735ccfad61628107327cfb25e49f8248b (diff) | |
download | FreeBSD-src-98a481610a9dcb442e9c2e851c6ef2a330027e45.zip FreeBSD-src-98a481610a9dcb442e9c2e851c6ef2a330027e45.tar.gz |
Replace the at_fork, at_exec, and at_exit functions with the slightly more
flexible process_fork, process_exec, and process_exit eventhandlers. This
reduces code duplication and also means that I don't have to go duplicate
the eventhandler locking three more times for each of at_fork, at_exec, and
at_exit.
Reviewed by: phk, jake, almost complete silence on arch@
Diffstat (limited to 'sys/kern')
-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 |
6 files changed, 37 insertions, 226 deletions
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; |