summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorthompsa <thompsa@FreeBSD.org>2009-12-17 21:17:13 +0000
committerthompsa <thompsa@FreeBSD.org>2009-12-17 21:17:13 +0000
commit86f640f7c3d9105c55e07ee1ec79221f09771fb8 (patch)
treec370b5f0cdc8d1c1c9dda6d153ac8eaf0cd1e050 /sys/kern
parent1c45e9d066d4ecb8cacedc35f63e52ae82ea470d (diff)
downloadFreeBSD-src-86f640f7c3d9105c55e07ee1ec79221f09771fb8.zip
FreeBSD-src-86f640f7c3d9105c55e07ee1ec79221f09771fb8.tar.gz
If the runcount is non-zero in eventhandler_deregister() then one or more
threads are executing the eventhandler, sleep in this case to make it safe for module unload. If the runcount was up then an entry would have been marked EHE_DEAD_PRIORITY so use this as a trigger to do the wakeup in eventhandler_prune_list(). Reviewed by: jhb
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/subr_eventhandler.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/sys/kern/subr_eventhandler.c b/sys/kern/subr_eventhandler.c
index f9c8ead..37c482c 100644
--- a/sys/kern/subr_eventhandler.c
+++ b/sys/kern/subr_eventhandler.c
@@ -178,6 +178,8 @@ eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag)
ep->ee_priority = EHE_DEAD_PRIORITY;
}
}
+ while (list->el_runcount > 0)
+ mtx_sleep(list, &list->el_lock, 0, "evhrm", 0);
EHL_UNLOCK(list);
}
@@ -225,16 +227,17 @@ void
eventhandler_prune_list(struct eventhandler_list *list)
{
struct eventhandler_entry *ep, *en;
+ int pruned = 0;
CTR2(KTR_EVH, "%s: pruning list \"%s\"", __func__, list->el_name);
EHL_LOCK_ASSERT(list, MA_OWNED);
- ep = TAILQ_FIRST(&list->el_entries);
- while (ep != NULL) {
- en = TAILQ_NEXT(ep, ee_link);
+ TAILQ_FOREACH_SAFE(ep, &list->el_entries, ee_link, en) {
if (ep->ee_priority == EHE_DEAD_PRIORITY) {
TAILQ_REMOVE(&list->el_entries, ep, ee_link);
free(ep, M_EVENTHANDLER);
+ pruned++;
}
- ep = en;
}
+ if (pruned > 0)
+ wakeup(list);
}
OpenPOWER on IntegriCloud