git: 9front

Download patch

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;
--