diff options
| author | cinap_lenrek <cinap_lenrek@gmx.de> | 2012-08-24 12:52:34 +0200 |
|---|---|---|
| committer | cinap_lenrek <cinap_lenrek@gmx.de> | 2012-08-24 12:52:34 +0200 |
| commit | 80a5bfc1d812618d4f6a16eb29026f412df7b56c (patch) | |
| tree | ad8ef92deab8f1131c37e41c534fa15ed067bcc6 | |
| parent | 8e5dd37eba4a206f875f6957aece99774933429e (diff) | |
| download | plan9front-80a5bfc1d812618d4f6a16eb29026f412df7b56c.tar.xz | |
sdvirtio: be more carefull at wakeup
wakeup cannot access r->sleep once we set r->done because the
sleeper might just return at this point making r invalid. make
a copy of the sleep rendez pointer before setting r->done.
| -rw-r--r-- | sys/src/9/pc/sdvirtio.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/sys/src/9/pc/sdvirtio.c b/sys/src/9/pc/sdvirtio.c index 982ac51e9..2ccc3dbce 100644 --- a/sys/src/9/pc/sdvirtio.c +++ b/sys/src/9/pc/sdvirtio.c @@ -218,6 +218,7 @@ viointerrupt(Ureg *, void *arg) { int id, free, m; struct Rock *r; + Rendez *z; Vqueue *q; Vdev *vd; @@ -231,8 +232,10 @@ viointerrupt(Ureg *, void *arg) id = q->usedent[q->lastused++ & m].id; if(r = q->rock[id]){ q->rock[id] = nil; - r->done = 1; - wakeup(r->sleep); + z = r->sleep; + r->done = 1; /* hands off */ + if(z != nil) + wakeup(z); } do { free = id; |
