Index: usr.sbin/bhyve/mevent.c =================================================================== --- usr.sbin/bhyve/mevent.c +++ usr.sbin/bhyve/mevent.c @@ -62,12 +62,6 @@ #define MEVENT_MAX 64 -#define MEV_ADD 1 -#define MEV_ENABLE 2 -#define MEV_DISABLE 3 -#define MEV_DEL_PENDING 4 -#define MEV_ADD_DISABLED 5 - extern char *vmname; static pthread_t mevent_tid; @@ -83,7 +77,7 @@ enum ev_type me_type; void *me_param; int me_cq; - int me_state; + int me_state; /* Desired kevent flags. */ int me_closefd; LIST_ENTRY(mevent) me_list; }; @@ -153,35 +147,6 @@ return (retval); } -static int -mevent_kq_flags(struct mevent *mevp) -{ - int ret; - - switch (mevp->me_state) { - case MEV_ADD: - ret = EV_ADD; /* implicitly enabled */ - break; - case MEV_ADD_DISABLED: - ret = EV_ADD | EV_DISABLE; - break; - case MEV_ENABLE: - ret = EV_ENABLE; - break; - case MEV_DISABLE: - ret = EV_DISABLE; - break; - case MEV_DEL_PENDING: - ret = EV_DELETE; - break; - default: - assert(0); - break; - } - - return (ret); -} - static int mevent_kq_fflags(struct mevent *mevp) { @@ -215,7 +180,7 @@ kev[i].data = 0; } kev[i].filter = mevent_kq_filter(mevp); - kev[i].flags = mevent_kq_flags(mevp); + kev[i].flags = mevp->me_state; kev[i].fflags = mevent_kq_fflags(mevp); kev[i].udata = mevp; i++; @@ -224,9 +189,15 @@ mevp->me_cq = 0; LIST_REMOVE(mevp, me_list); - if (mevp->me_state == MEV_DEL_PENDING) { + if (mevp->me_state & EV_DELETE) { free(mevp); } else { + /* + * We need to add the event only once, so we can + * reset the EV_ADD bit after it has been propagated + * to the kevent() arguments the first time. + */ + mevp->me_state &= ~EV_ADD; LIST_INSERT_HEAD(&global_head, mevp, me_list); } @@ -318,7 +289,7 @@ void (*func)(int, enum ev_type, void *), void *param) { - return mevent_add_state(tfd, type, func, param, MEV_ADD); + return mevent_add_state(tfd, type, func, param, EV_ADD); } struct mevent * @@ -326,18 +297,29 @@ void (*func)(int, enum ev_type, void *), void *param) { - return mevent_add_state(tfd, type, func, param, MEV_ADD_DISABLED); + return mevent_add_state(tfd, type, func, param, EV_ADD | EV_DISABLE); } static int -mevent_update(struct mevent *evp, int newstate) +mevent_update(struct mevent *evp, bool enable) { + int newstate; + /* * It's not possible to enable/disable a deleted event */ - if (evp->me_state == MEV_DEL_PENDING) + if (evp->me_state & EV_DELETE) return (EINVAL); + newstate = evp->me_state; + if (enable) { + newstate |= EV_ENABLE; + newstate &= ~EV_DISABLE; + } else { + newstate |= EV_DISABLE; + newstate &= ~EV_ENABLE; + } + /* * No update needed if state isn't changing */ @@ -367,14 +349,14 @@ mevent_enable(struct mevent *evp) { - return (mevent_update(evp, MEV_ENABLE)); + return (mevent_update(evp, true)); } int mevent_disable(struct mevent *evp) { - return (mevent_update(evp, MEV_DISABLE)); + return (mevent_update(evp, false)); } static int @@ -392,7 +374,7 @@ LIST_INSERT_HEAD(&change_head, evp, me_list); mevent_notify(); } - evp->me_state = MEV_DEL_PENDING; + evp->me_state = EV_DELETE; if (closefd) evp->me_closefd = 1;