diff options
| -rw-r--r-- | sys/kern/subr_eventhandler.c | 18 | ||||
| -rw-r--r-- | sys/sys/eventhandler.h | 4 |
2 files changed, 16 insertions, 6 deletions
diff --git a/sys/kern/subr_eventhandler.c b/sys/kern/subr_eventhandler.c index 7568101dabd2..e91647648995 100644 --- a/sys/kern/subr_eventhandler.c +++ b/sys/kern/subr_eventhandler.c @@ -198,7 +198,10 @@ _eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag, } else { CTR3(KTR_EVH, "%s: marking item %p from \"%s\" as dead", __func__, ep, list->el_name); + KASSERT(ep->ee_priority != EHE_DEAD_PRIORITY, + ("%s: handler for %s is dead", __func__, list->el_name)); ep->ee_priority = EHE_DEAD_PRIORITY; + list->el_deadcount++; } } else { /* remove entire list */ @@ -213,11 +216,15 @@ _eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag, } else { CTR2(KTR_EVH, "%s: marking all items from \"%s\" as dead", __func__, list->el_name); - TAILQ_FOREACH(ep, &list->el_entries, ee_link) + TAILQ_FOREACH(ep, &list->el_entries, ee_link) { + KASSERT(ep->ee_priority != EHE_DEAD_PRIORITY, + ("%s: handler for %s is dead", __func__, list->el_name)); ep->ee_priority = EHE_DEAD_PRIORITY; + list->el_deadcount++; + } } } - while (wait && list->el_runcount > 0) + while (wait && list->el_deadcount > 0) mtx_sleep(list, &list->el_lock, 0, "evhrm", 0); EHL_UNLOCK(list); } @@ -292,8 +299,11 @@ eventhandler_prune_list(struct eventhandler_list *list) pruned++; } } - if (pruned > 0) - wakeup(list); + KASSERT(pruned == list->el_deadcount, + ("%s: pruned %u entries from \"%s\" but expected %u", + __func__, pruned, list->el_name, list->el_deadcount)); + list->el_deadcount = 0; + wakeup(list); } /* diff --git a/sys/sys/eventhandler.h b/sys/sys/eventhandler.h index 29a16b393b52..f37b1150a7e8 100644 --- a/sys/sys/eventhandler.h +++ b/sys/sys/eventhandler.h @@ -46,7 +46,7 @@ struct eventhandler_entry_vimage { struct eventhandler_list { char *el_name; - int el_flags; /* Unused. */ + u_int el_deadcount; u_int el_runcount; struct mtx el_lock; TAILQ_ENTRY(eventhandler_list) el_link; @@ -82,7 +82,7 @@ struct eventhandler_list { KASSERT((list)->el_runcount > 0, \ ("eventhandler_invoke: runcount underflow")); \ (list)->el_runcount--; \ - if ((list)->el_runcount == 0) \ + if ((list)->el_runcount == 0 && (list)->el_deadcount != 0) \ eventhandler_prune_list(list); \ EHL_UNLOCK((list)); \ } while (0) |
