summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>2010-06-08 22:40:02 +0000
committermjacob <mjacob@FreeBSD.org>2010-06-08 22:40:02 +0000
commitd16c7840fb2be941c8009cfd9e3a8c2c55c09290 (patch)
treedbc46b42b75f39f4278406d6fa37d2b00eeda0d5
parentf6ce2bf5e8a87436f3476b2526363cdc1ad5cca4 (diff)
downloadFreeBSD-src-d16c7840fb2be941c8009cfd9e3a8c2c55c09290.zip
FreeBSD-src-d16c7840fb2be941c8009cfd9e3a8c2c55c09290.tar.gz
Try and narrow the gap in which you act on an event that has been canceled.
Obtained from: Jaako Heinonen MFC after: 1 month
-rw-r--r--sys/geom/geom_event.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/sys/geom/geom_event.c b/sys/geom/geom_event.c
index 9880454..5ac52d4 100644
--- a/sys/geom/geom_event.c
+++ b/sys/geom/geom_event.c
@@ -76,6 +76,7 @@ struct g_event {
#define EV_DONE 0x80000
#define EV_WAKEUP 0x40000
#define EV_CANCELED 0x20000
+#define EV_INPROGRESS 0x10000
void
g_waitidle(void)
@@ -206,12 +207,19 @@ one_event(void)
g_topology_unlock();
return (0);
}
+ if (ep->flag & EV_INPROGRESS) {
+ mtx_unlock(&g_eventlock);
+ g_topology_unlock();
+ return (1);
+ }
+ ep->flag |= EV_INPROGRESS;
mtx_unlock(&g_eventlock);
g_topology_assert();
ep->func(ep->arg, 0);
g_topology_assert();
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;
@@ -255,6 +263,8 @@ g_cancel_event(void *ref)
break;
}
TAILQ_FOREACH_SAFE(ep, &g_events, events, epn) {
+ if (ep->flag & EV_INPROGRESS)
+ continue;
for (n = 0; n < G_N_EVENTREFS; n++) {
if (ep->ref[n] == NULL)
break;
OpenPOWER on IntegriCloud