summaryrefslogtreecommitdiffstats
path: root/sys/geom
diff options
context:
space:
mode:
authorjh <jh@FreeBSD.org>2010-11-03 16:19:35 +0000
committerjh <jh@FreeBSD.org>2010-11-03 16:19:35 +0000
commit6604019e2651e5c8091a892c712c67a1c4278903 (patch)
tree7de24b408f50a5fed2c0731b48fa1deaf109deb6 /sys/geom
parent177b41b47d00bee38872e7f187a336e26b8286fd (diff)
downloadFreeBSD-src-6604019e2651e5c8091a892c712c67a1c4278903.zip
FreeBSD-src-6604019e2651e5c8091a892c712c67a1c4278903.tar.gz
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
Diffstat (limited to 'sys/geom')
-rw-r--r--sys/geom/geom_event.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/sys/geom/geom_event.c b/sys/geom/geom_event.c
index 5ac52d4..44890aa 100644
--- a/sys/geom/geom_event.c
+++ b/sys/geom/geom_event.c
@@ -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);
}
OpenPOWER on IntegriCloud