#define SUDO_EVLOOP_NONBLOCK 0x02 /* Do not block in event loop */
/* Event base flags (internal) */
-#define SUDO_EVBASE_LOOPEXIT 0x01
-#define SUDO_EVBASE_LOOPBREAK 0x02
-#define SUDO_EVBASE_LOOPCONT 0x04
+#define SUDO_EVBASE_LOOPONCE SUDO_EVLOOP_ONCE
+#define SUDO_EVBASE_LOOPEXIT 0x02
+#define SUDO_EVBASE_LOOPBREAK 0x04
+#define SUDO_EVBASE_LOOPCONT 0x08
#define SUDO_EVBASE_GOT_EXIT 0x10
#define SUDO_EVBASE_GOT_BREAK 0x20
#define SUDO_EVBASE_GOT_MASK 0xf0
* If sudo_ev_loopexit() was called when events were not running
* the next invocation of sudo_ev_loop() only runs once.
* All other base flags are ignored unless we are running events.
+ * Note that SUDO_EVLOOP_ONCE and SUDO_EVBASE_LOOPONCE are equivalent.
*/
- if (ISSET(base->flags, SUDO_EVBASE_LOOPEXIT))
- SET(flags, SUDO_EVLOOP_ONCE);
- base->flags = 0;
+ base->flags |= (flags & SUDO_EVLOOP_ONCE);
+ base->flags &= (SUDO_EVBASE_LOOPEXIT|SUDO_EVBASE_LOOPONCE);
for (;;) {
rescan:
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)) {
- sudo_ev_deactivate_all(base);
- goto rescan;
- }
+ sudo_ev_deactivate_all(base);
+ goto rescan;
}
}
- if (ISSET(base->flags, SUDO_EVBASE_LOOPEXIT)) {
- /* exit loop after once through */
- SET(base->flags, SUDO_EVBASE_GOT_EXIT);
- sudo_ev_deactivate_all(base);
- break;
- }
- if (ISSET(flags, SUDO_EVLOOP_ONCE)) {
+ if (ISSET(base->flags, SUDO_EVBASE_LOOPONCE)) {
+ /* SUDO_EVBASE_LOOPEXIT is always set w/ SUDO_EVBASE_LOOPONCE */
+ if (ISSET(base->flags, SUDO_EVBASE_LOOPEXIT))
+ SET(base->flags, SUDO_EVBASE_GOT_EXIT);
sudo_ev_deactivate_all(base);
break;
}
sudo_ev_loopexit_v1(struct sudo_event_base *base)
{
debug_decl(sudo_ev_loopexit, SUDO_DEBUG_EVENT)
- SET(base->flags, SUDO_EVBASE_LOOPEXIT);
+ /* SUDO_EVBASE_LOOPBREAK trumps SUDO_EVBASE_LOOPEXIT */
+ if (!ISSET(base->flags, SUDO_EVBASE_LOOPBREAK)) {
+ /* SUDO_EVBASE_LOOPEXIT trumps SUDO_EVBASE_LOOPCONT */
+ CLR(base->flags, SUDO_EVBASE_LOOPCONT);
+ SET(base->flags, (SUDO_EVBASE_LOOPEXIT|SUDO_EVBASE_LOOPONCE));
+ }
debug_return;
}
sudo_ev_loopbreak_v1(struct sudo_event_base *base)
{
debug_decl(sudo_ev_loopbreak, SUDO_DEBUG_EVENT)
+ /* SUDO_EVBASE_LOOPBREAK trumps SUDO_EVBASE_LOOP{CONT,EXIT,ONCE}. */
+ CLR(base->flags, (SUDO_EVBASE_LOOPCONT|SUDO_EVBASE_LOOPEXIT|SUDO_EVBASE_LOOPONCE));
SET(base->flags, SUDO_EVBASE_LOOPBREAK);
debug_return;
}
sudo_ev_loopcontinue_v1(struct sudo_event_base *base)
{
debug_decl(sudo_ev_loopcontinue, SUDO_DEBUG_EVENT)
- SET(base->flags, SUDO_EVBASE_LOOPCONT);
+ /* SUDO_EVBASE_LOOP{BREAK,EXIT} trumps SUDO_EVBASE_LOOPCONT */
+ if (!ISSET(base->flags, SUDO_EVBASE_LOOPONCE|SUDO_EVBASE_LOOPBREAK)) {
+ SET(base->flags, SUDO_EVBASE_LOOPCONT);
+ }
debug_return;
}