shithub: riscv

Download patch

ref: 80a5bfc1d812618d4f6a16eb29026f412df7b56c
parent: 8e5dd37eba4a206f875f6957aece99774933429e
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;
--