diff options
author | jhb <jhb@FreeBSD.org> | 2000-12-12 04:01:35 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2000-12-12 04:01:35 +0000 |
commit | 94f4cb07c81982d8e58187be141b0af4fd48496e (patch) | |
tree | 512112db07d61b8f51fee7a3f53f4f906b2183e6 /sys/kern | |
parent | e1f16f459e131a27f41f02692b2b26c6f1316def (diff) | |
download | FreeBSD-src-94f4cb07c81982d8e58187be141b0af4fd48496e.zip FreeBSD-src-94f4cb07c81982d8e58187be141b0af4fd48496e.tar.gz |
- Convert the per-eventhandler list mutex to a lockmgr lock so that it can
be safely held across an eventhandler function call.
- Fix an instance of the head of an eventhandler list being read without
the lock being held.
- Break down and use a SYSINIT at the new SI_SUB_EVENTHANDLER to initialize
the eventhandler global mutex and the eventhandler list of lists rather
than using a non-MP safe initialization during the first call to
eventhandler_register().
- Add in a KASSERT() to eventhandler_register() to ensure that we don't try
to register an eventhandler before things have been initialized.
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/subr_eventhandler.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/sys/kern/subr_eventhandler.c b/sys/kern/subr_eventhandler.c index 417d73e..ca35a05 100644 --- a/sys/kern/subr_eventhandler.c +++ b/sys/kern/subr_eventhandler.c @@ -29,6 +29,7 @@ #include <sys/param.h> #include <sys/kernel.h> #include <sys/malloc.h> +#include <sys/mutex.h> #include <sys/systm.h> #include <sys/eventhandler.h> @@ -45,6 +46,19 @@ struct eventhandler_entry_generic void (* func)(void); }; +/* + * Initialize the eventhandler mutex and list. + */ +static void +eventhandler_init(void *dummy __unused) +{ + TAILQ_INIT(&eventhandler_lists); + mtx_init(&eventhandler_mutex, "eventhandler", MTX_DEF); + eventhandler_lists_initted = 1; +} +SYSINIT(eventhandlers, SI_SUB_EVENTHANDLER, SI_ORDER_FIRST, eventhandler_init, + NULL) + /* * Insertion is O(n) due to the priority scan, but optimises to O(1) * if all priorities are identical. @@ -56,12 +70,7 @@ eventhandler_register(struct eventhandler_list *list, char *name, struct eventhandler_entry_generic *eg; struct eventhandler_entry *ep; - /* avoid the need for a SYSINIT just to init the list */ - if (!eventhandler_lists_initted) { - TAILQ_INIT(&eventhandler_lists); - mtx_init(&eventhandler_mutex, "eventhandler", MTX_DEF); - eventhandler_lists_initted = 1; - } + KASSERT(eventhandler_lists_initted, ("eventhandler registered too early")); /* lock the eventhandler lists */ mtx_enter(&eventhandler_mutex, MTX_DEF); @@ -86,7 +95,7 @@ eventhandler_register(struct eventhandler_list *list, char *name, } if (!(list->el_flags & EHE_INITTED)) { TAILQ_INIT(&list->el_entries); - mtx_init(&list->el_mutex, name, MTX_DEF); + lockinit(&list->el_lock, PZERO, name, 0, 0); list->el_flags = EHE_INITTED; } @@ -101,7 +110,7 @@ eventhandler_register(struct eventhandler_list *list, char *name, eg->ee.ee_priority = priority; /* sort it into the list */ - mtx_enter(&list->el_mutex, MTX_DEF); + lockmgr(&list->el_lock, LK_EXCLUSIVE, NULL, CURPROC); for (ep = TAILQ_FIRST(&list->el_entries); ep != NULL; ep = TAILQ_NEXT(ep, ee_link)) { @@ -112,7 +121,7 @@ eventhandler_register(struct eventhandler_list *list, char *name, } if (ep == NULL) TAILQ_INSERT_TAIL(&list->el_entries, &eg->ee, ee_link); - mtx_exit(&list->el_mutex, MTX_DEF); + lockmgr(&list->el_lock, LK_RELEASE, NULL, CURPROC); mtx_exit(&eventhandler_mutex, MTX_DEF); return(&eg->ee); } @@ -123,7 +132,7 @@ eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag) struct eventhandler_entry *ep = tag; /* XXX insert diagnostic check here? */ - mtx_enter(&list->el_mutex, MTX_DEF); + lockmgr(&list->el_lock, LK_EXCLUSIVE, NULL, CURPROC); if (ep != NULL) { /* remove just this entry */ TAILQ_REMOVE(&list->el_entries, ep, ee_link); @@ -136,7 +145,7 @@ eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag) free(ep, M_EVENTHANDLER); } } - mtx_exit(&list->el_mutex, MTX_DEF); + lockmgr(&list->el_lock, LK_RELEASE, NULL, CURPROC); } struct eventhandler_list * |