diff --git a/include/sudo_event.h b/include/sudo_event.h index 37bf36437..8dad43ba1 100644 --- a/include/sudo_event.h +++ b/include/sudo_event.h @@ -147,6 +147,9 @@ __dso_public bool sudo_ev_got_break_v1(struct sudo_event_base *base); /* Magic pointer value to use self pointer as callback arg. */ #define sudo_ev_self_cbarg() ((void *)-1) +/* Add an event to the base's active queue and mark it active (internal). */ +void sudo_ev_activate(struct sudo_event_base *base, struct sudo_event *ev); + /* * Backend implementation. */ diff --git a/lib/util/event.c b/lib/util/event.c index 0f28dd1e9..232216182 100644 --- a/lib/util/event.c +++ b/lib/util/event.c @@ -52,6 +52,38 @@ /* XXX - use non-exiting allocators? */ +/* + * Add an event to the base's active queue and mark it active. + */ +void +sudo_ev_activate(struct sudo_event_base *base, struct sudo_event *ev) +{ + TAILQ_INSERT_TAIL(&base->active, ev, active_entries); + SET(ev->flags, SUDO_EVQ_ACTIVE); +} + +/* + * Remove an event from the base's active queue and mark it inactive. + */ +static inline void +sudo_ev_deactivate(struct sudo_event_base *base, struct sudo_event *ev) +{ + CLR(ev->flags, SUDO_EVQ_ACTIVE); + TAILQ_REMOVE(&base->active, ev, active_entries); +} + +/* + * Clear out the base's active queue and mark all events as inactive. + */ +static void +sudo_ev_deactivate_all(struct sudo_event_base *base) +{ + struct sudo_event *ev; + + while ((ev = TAILQ_FIRST(&base->active)) != NULL) + sudo_ev_deactivate(base, ev); +} + struct sudo_event_base * sudo_ev_base_alloc_v1(void) { @@ -305,8 +337,7 @@ rescan: */ while ((ev = TAILQ_FIRST(&base->active)) != NULL) { /* Pop first event off the active queue. */ - CLR(ev->flags, SUDO_EVQ_ACTIVE); - TAILQ_REMOVE(&base->active, ev, active_entries); + sudo_ev_deactivate(base, ev); /* Remove from base unless persistent. */ if (!ISSET(ev->events, SUDO_EV_PERSIST)) sudo_ev_del(base, ev); @@ -315,20 +346,14 @@ rescan: if (ISSET(base->flags, SUDO_EVBASE_LOOPBREAK)) { /* Stop processing events immediately. */ SET(base->flags, SUDO_EVBASE_GOT_BREAK); - while ((ev = TAILQ_FIRST(&base->active)) != NULL) { - CLR(ev->flags, SUDO_EVQ_ACTIVE); - TAILQ_REMOVE(&base->active, ev, active_entries); - } + sudo_ev_deactivate_all(base); goto done; } if (ISSET(base->flags, SUDO_EVBASE_LOOPCONT)) { /* Rescan events and start polling again. */ CLR(base->flags, SUDO_EVBASE_LOOPCONT); if (!ISSET(flags, SUDO_EVLOOP_ONCE)) { - while ((ev = TAILQ_FIRST(&base->active)) != NULL) { - CLR(ev->flags, SUDO_EVQ_ACTIVE); - TAILQ_REMOVE(&base->active, ev, active_entries); - } + sudo_ev_deactivate_all(base); goto rescan; } } @@ -336,10 +361,13 @@ rescan: if (ISSET(base->flags, SUDO_EVBASE_LOOPEXIT)) { /* exit loop after once through */ SET(base->flags, SUDO_EVBASE_GOT_EXIT); - goto done; - } - if (ISSET(flags, SUDO_EVLOOP_ONCE)) + sudo_ev_deactivate_all(base); break; + } + if (ISSET(flags, SUDO_EVLOOP_ONCE)) { + sudo_ev_deactivate_all(base); + break; + } } done: base->flags &= SUDO_EVBASE_GOT_MASK; diff --git a/lib/util/event_poll.c b/lib/util/event_poll.c index b2b81b84a..a7f047edd 100644 --- a/lib/util/event_poll.c +++ b/lib/util/event_poll.c @@ -173,8 +173,7 @@ sudo_ev_scan_impl(struct sudo_event_base *base, int flags) "%s: polled fd %d, events %d, activating %p", __func__, ev->fd, what, ev); ev->revents = what; - TAILQ_INSERT_TAIL(&base->active, ev, active_entries); - SET(ev->flags, SUDO_EVQ_ACTIVE); + sudo_ev_activate(base, ev); } } break; diff --git a/lib/util/event_select.c b/lib/util/event_select.c index 7e7b6f6f3..30c9301c1 100644 --- a/lib/util/event_select.c +++ b/lib/util/event_select.c @@ -201,8 +201,7 @@ sudo_ev_scan_impl(struct sudo_event_base *base, int flags) "%s: selected fd %d, events %d, activating %p", __func__, ev->fd, what, ev); ev->revents = what; - TAILQ_INSERT_TAIL(&base->active, ev, active_entries); - SET(ev->flags, SUDO_EVQ_ACTIVE); + sudo_ev_activate(base, ev); } } }