shithub: riscv

Download patch

ref: 23b189c2bcf2de03902ef0f18e23cf030c6d072a
parent: 5f54eaddba800ec81c65ab17fa17ddd91cc66470
author: cinap_lenrek <[email protected]>
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;