diff options
author | msmith <msmith@FreeBSD.org> | 2000-09-22 03:17:35 +0000 |
---|---|---|
committer | msmith <msmith@FreeBSD.org> | 2000-09-22 03:17:35 +0000 |
commit | a4bf8740bb46d337eb18ae335c2f3b023098c63d (patch) | |
tree | 7dc902f0062c1043cfe696da65a875dca8055932 /sys/kern/subr_eventhandler.c | |
parent | 433760d5d5c544a818db7670c31b779972d399ec (diff) | |
download | FreeBSD-src-a4bf8740bb46d337eb18ae335c2f3b023098c63d.zip FreeBSD-src-a4bf8740bb46d337eb18ae335c2f3b023098c63d.tar.gz |
Make the EVENTHANDLER mechanism MP-safe. Events can now be invoked
without holding the Giant lock.
Diffstat (limited to 'sys/kern/subr_eventhandler.c')
-rw-r--r-- | sys/kern/subr_eventhandler.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/sys/kern/subr_eventhandler.c b/sys/kern/subr_eventhandler.c index c23441d..1b9b739 100644 --- a/sys/kern/subr_eventhandler.c +++ b/sys/kern/subr_eventhandler.c @@ -58,9 +58,13 @@ eventhandler_register(struct eventhandler_list *list, char *name, /* 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; } + /* lock the eventhandler lists */ + mtx_enter(&eventhandler_mutex, MTX_DEF); + /* Do we need to find/create the (slow) list? */ if (list == NULL) { /* look for a matching, existing list */ @@ -69,8 +73,10 @@ eventhandler_register(struct eventhandler_list *list, char *name, /* Do we need to create the list? */ if (list == NULL) { if ((list = malloc(sizeof(struct eventhandler_list) + strlen(name) + 1, - M_EVENTHANDLER, M_NOWAIT)) == NULL) + M_EVENTHANDLER, M_NOWAIT)) == NULL) { + mtx_exit(&eventhandler_mutex, MTX_DEF); return(NULL); + } list->el_flags = 0; list->el_name = (char *)list + sizeof(struct eventhandler_list); strcpy(list->el_name, name); @@ -79,18 +85,22 @@ 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); list->el_flags = EHE_INITTED; } /* allocate an entry for this handler, populate it */ if ((eg = malloc(sizeof(struct eventhandler_entry_generic), - M_EVENTHANDLER, M_NOWAIT)) == NULL) + M_EVENTHANDLER, M_NOWAIT)) == NULL) { + mtx_exit(&eventhandler_mutex, MTX_DEF); return(NULL); + } eg->func = func; eg->ee.ee_arg = arg; eg->ee.ee_priority = priority; /* sort it into the list */ + mtx_enter(&list->el_mutex, MTX_DEF); for (ep = TAILQ_FIRST(&list->el_entries); ep != NULL; ep = TAILQ_NEXT(ep, ee_link)) { @@ -101,6 +111,8 @@ 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); + mtx_exit(&eventhandler_mutex, MTX_DEF); return(&eg->ee); } @@ -110,6 +122,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); if (ep != NULL) { /* remove just this entry */ TAILQ_REMOVE(&list->el_entries, ep, ee_link); @@ -122,19 +135,24 @@ eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag) free(ep, M_EVENTHANDLER); } } + mtx_exit(&list->el_mutex, MTX_DEF); } struct eventhandler_list * eventhandler_find_list(char *name) { struct eventhandler_list *list; - + /* scan looking for the requested list */ + mtx_enter(&eventhandler_mutex, MTX_DEF); for (list = TAILQ_FIRST(&eventhandler_lists); list != NULL; list = TAILQ_NEXT(list, el_link)) { if (!strcmp(name, list->el_name)) break; } + mtx_exit(&eventhandler_mutex, MTX_DEF); + return(list); } + |