diff options
author | msmith <msmith@FreeBSD.org> | 2000-10-09 00:41:29 +0000 |
---|---|---|
committer | msmith <msmith@FreeBSD.org> | 2000-10-09 00:41:29 +0000 |
commit | 12c1416afe977a7848d0bd1aab42981d69b6933a (patch) | |
tree | b9350cda5a63c8769e746096273a5ce555d513f9 /sys | |
parent | 62cf720766d52fe137a61d39461e57eef44bfc66 (diff) | |
download | FreeBSD-src-12c1416afe977a7848d0bd1aab42981d69b6933a.zip FreeBSD-src-12c1416afe977a7848d0bd1aab42981d69b6933a.tar.gz |
Change the way that eventhandler lists are processed so that an event
handler can safely remove itself from a list while being run.
(Note that it is not safe to remove anything else from the same list,
as this may still cause corruption in the case where the removed
item is next on the list.)
Diffstat (limited to 'sys')
-rw-r--r-- | sys/sys/eventhandler.h | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/sys/sys/eventhandler.h b/sys/sys/eventhandler.h index 601b7db..3fc4060 100644 --- a/sys/sys/eventhandler.h +++ b/sys/sys/eventhandler.h @@ -79,13 +79,15 @@ struct __hack do { \ struct eventhandler_list *_el = &Xeventhandler_list_ ## name ; \ struct eventhandler_entry *_ep = TAILQ_FIRST(&(_el->el_entries)); \ + struct eventhandler_entry *_en; \ \ if (_el->el_flags & EHE_INITTED) { \ mtx_enter(&_el->el_mutex, MTX_DEF); \ while (_ep != NULL) { \ + _en = TAILQ_NEXT(_ep, ee_link); \ ((struct eventhandler_entry_ ## name *)_ep)->eh_func(_ep->ee_arg , \ ## args); \ - _ep = TAILQ_NEXT(_ep, ee_link); \ + _ep = _en; \ } \ mtx_exit(&_el->el_mutex, MTX_DEF); \ } \ @@ -115,16 +117,17 @@ struct __hack #define EVENTHANDLER_INVOKE(name, args...) \ do { \ struct eventhandler_list *_el; \ - struct eventhandler_entry *_ep; \ + struct eventhandler_entry *_ep, *_en; \ \ if (((_el = eventhandler_find_list(#name)) != NULL) && \ (_el->el_flags & EHE_INITTED)) { \ mtx_enter(&_el->el_mutex, MTX_DEF); \ - for (_ep = TAILQ_FIRST(&(_el->el_entries)); \ - _ep != NULL; \ - _ep = TAILQ_NEXT(_ep, ee_link)) { \ + _ep = TAILQ_FIRST(&(_el->el_entries)); \ + while (_ep != NULL) { \ + _en = TAILQ_NEXT(_ep, ee_link); \ ((struct eventhandler_entry_ ## name *)_ep)->eh_func(_ep->ee_arg , \ ## args); \ + _ep = _en; \ } \ mtx_exit(&_el->el_mutex, MTX_DEF); \ } \ @@ -169,6 +172,7 @@ EVENTHANDLER_DECLARE(shutdown_final, shutdown_fn); /* Idle process event */ typedef void (*idle_eventhandler_t) __P((void *, int)); +#define IDLE_PRI_FIRST 10000 #define IDLE_PRI_LAST 20000 EVENTHANDLER_FAST_DECLARE(idle_event, idle_eventhandler_t); |