ref: b4e7116f3a55b1b228adef6b8f1a8887792c4a97
parent: 9ade24c8699a18a92c799cd5edffd6398fce5ea2
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Fri Aug 24 08:52:34 EDT 2012
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.
--- a/sys/src/9/pc/sdvirtio.c
+++ b/sys/src/9/pc/sdvirtio.c
@@ -218,6 +218,7 @@
{int id, free, m;
struct Rock *r;
+ Rendez *z;
Vqueue *q;
Vdev *vd;
@@ -231,8 +232,10 @@
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;
--
⑨