Extend the g_eventlock mutex coverage in one_event() to include setting
of the EV_DONE flag and use the mutex to protect against losing wakeups in g_waitfor_event(). Reported by: davidxu Tested by: davidxu Discussed on: freebsd-current
This commit is contained in:
parent
3350df4899
commit
9d142a6ee6
@ -220,11 +220,12 @@ one_event(void)
|
||||
mtx_lock(&g_eventlock);
|
||||
TAILQ_REMOVE(&g_events, ep, events);
|
||||
ep->flag &= ~EV_INPROGRESS;
|
||||
mtx_unlock(&g_eventlock);
|
||||
if (ep->flag & EV_WAKEUP) {
|
||||
ep->flag |= EV_DONE;
|
||||
mtx_unlock(&g_eventlock);
|
||||
wakeup(ep);
|
||||
} else {
|
||||
mtx_unlock(&g_eventlock);
|
||||
g_free(ep);
|
||||
}
|
||||
g_topology_unlock();
|
||||
@ -365,11 +366,14 @@ g_waitfor_event(g_event_t *func, void *arg, int flag, ...)
|
||||
va_end(ap);
|
||||
if (error)
|
||||
return (error);
|
||||
do
|
||||
tsleep(ep, PRIBIO, "g_waitfor_event", hz);
|
||||
while (!(ep->flag & EV_DONE));
|
||||
|
||||
mtx_lock(&g_eventlock);
|
||||
while (!(ep->flag & EV_DONE))
|
||||
msleep(ep, &g_eventlock, PRIBIO, "g_waitfor_event", hz);
|
||||
if (ep->flag & EV_CANCELED)
|
||||
error = EAGAIN;
|
||||
mtx_unlock(&g_eventlock);
|
||||
|
||||
g_free(ep);
|
||||
return (error);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user