git: 9front

Download patch

ref: 7658855dccff0f3fbef70fe3a5baa719217bbd01
parent: f5a05b8c9347202965da838354cb9568c2667b51
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Thu Jan 10 17:16:23 EST 2013

libdraw: gengetwindow() resize race

instead of trying to make rio not change the window image too fast
and give the client some time to attach it (which turns out to be
impossible), we acknowledge that there is a race and just retry
the window reattach as long as the winname keeps changing in
gengetwindow().

--- a/sys/src/libdraw/init.c
+++ b/sys/src/libdraw/init.c
@@ -129,10 +129,12 @@
 gengetwindow(Display *d, char *winname, Image **winp, Screen **scrp, int ref)
 {
 	int n, fd;
-	char buf[64+1];
+	char buf[64+1], obuf[64+1];
 	Image *image;
 	Rectangle r;
 
+	obuf[0] = 0;
+retry:
 	fd = open(winname, OREAD);
 	if(fd<0 || (n=read(fd, buf, sizeof buf-1))<=0){
 		if((image=d->image) == nil){
@@ -147,6 +149,7 @@
 		buf[n] = '\0';
 		if(*winp != nil){
 			_freeimage1(*winp);
+			*winp = nil;
 			freeimage((*scrp)->image);
 			freescreen(*scrp);
 			*scrp = nil;
@@ -153,6 +156,15 @@
 		}
 		image = namedimage(d, buf);
 		if(image == 0){
+			/*
+			 * theres a race where the winname can change after
+			 * we read it, so keep trying as long as the name
+			 * keeps changing.
+			 */
+			if(strcmp(buf, obuf) != 0){
+				strcpy(obuf, buf);
+				goto retry;
+			}
 			fprint(2, "namedimage %s failed: %r\n", buf);
 			*winp = nil;
 			d->screenimage = nil;
--