Commit Diff


commit - d3864abaee496db2f97dff1dbf5c7766d4439c7b
commit + 3a19470202c5c0f6e9375e5d57535c3d508f2edf
blob - 53321fa5258886698e48b24b585ab427bfaf3f4b
blob + e9890fc31c8fbd67357a23e68bb855e64292095b
--- include/mux.h
+++ include/mux.h
@@ -19,6 +19,7 @@ struct Muxrpc
 	uint tag;
 	void *p;
 	int waiting;
+	int async;
 };
 
 struct Mux
@@ -27,7 +28,7 @@ struct Mux
 	uint maxtag;
 	int (*send)(Mux*, void*);
 	void *(*recv)(Mux*);
-	void *(*nbrecv)(Mux*);
+	int (*nbrecv)(Mux*, void**);
 	int (*gettag)(Mux*, void*);
 	int (*settag)(Mux*, void*, uint);
 	void *aux;	/* for private use by client */
@@ -52,18 +53,18 @@ void	muxinit(Mux*);
 void*	muxrpc(Mux*, void*);
 void	muxprocs(Mux*);
 Muxrpc*	muxrpcstart(Mux*, void*);
-void*	muxrpccanfinish(Muxrpc*);
+int	muxrpccanfinish(Muxrpc*, void**);
 
 /* private */
 int	_muxsend(Mux*, void*);
-void*	_muxrecv(Mux*, int);
+int	_muxrecv(Mux*, int, void**);
 void	_muxsendproc(void*);
 void	_muxrecvproc(void*);
 Muxqueue *_muxqalloc(void);
 int _muxqsend(Muxqueue*, void*);
 void *_muxqrecv(Muxqueue*);
 void _muxqhangup(Muxqueue*);
-void *_muxnbqrecv(Muxqueue*);
+int _muxnbqrecv(Muxqueue*, void**);
 
 #if defined(__cplusplus)
 }
blob - bf1262acb95cb08a255fd37dc71ac08e35291be8
blob + 9ad6054f06557163db683e6cf061f58c3e8339c7
--- src/cmd/devdraw/x11-init.c
+++ src/cmd/devdraw/x11-init.c
@@ -47,7 +47,8 @@ static int
 xioerror(XDisplay *d)
 {
 	/*print("X I/O error\n"); */
-	sysfatal("X I/O error\n");
+	exit(0);
+	/*sysfatal("X I/O error\n");*/
 	abort();
 	return -1;
 }
blob - 62615942c4eddc1cee2008c05b0867d11edc65b4
blob + 93c562351c7d33b2bd5e3f506a9171b82b822e3a
--- src/libdraw/drawclient.c
+++ src/libdraw/drawclient.c
@@ -13,7 +13,7 @@ int chattydrawclient;
 
 static int	drawgettag(Mux *mux, void *vmsg);
 static void*	drawrecv(Mux *mux);
-static void*	drawnbrecv(Mux *mux);
+static int	drawnbrecv(Mux *mux, void**);
 static int	drawsend(Mux *mux, void *vmsg);
 static int	drawsettag(Mux *mux, void *vmsg, uint tag);
 static int canreadfd(int);
@@ -83,40 +83,46 @@ drawsend(Mux *mux, void *vmsg)
 	return write(d->srvfd, msg, n);
 }
 
-static void*
-_drawrecv(Mux *mux, int nb)
+static int
+_drawrecv(Mux *mux, int canblock, void **vp)
 {
 	int n;
 	uchar buf[4], *p;
 	Display *d;
 
 	d = mux->aux;
-	if(nb && !canreadfd(d->srvfd))
-		return nil;
+	*vp = nil;
+	if(!canblock && !canreadfd(d->srvfd))
+		return 0;
 	if((n=readn(d->srvfd, buf, 4)) != 4)
-		return nil;
+		return 1;
 	GET(buf, n);
 	p = malloc(n);
 	if(p == nil){
 		fprint(2, "out of memory allocating %d in drawrecv\n", n);
-		return nil;
+		return 1;
 	}
 	memmove(p, buf, 4);
-	if(readn(d->srvfd, p+4, n-4) != n-4)
-		return nil;
-	return p;
+	if(readn(d->srvfd, p+4, n-4) != n-4){
+		free(p);
+		return 1;
+	}
+	*vp = p;
+	return 1;
 }
 
 static void*
 drawrecv(Mux *mux)
 {
-	return _drawrecv(mux, 0);
+	void *p;
+	_drawrecv(mux, 1, &p);
+	return p;
 }
 
-static void*
-drawnbrecv(Mux *mux)
+static int
+drawnbrecv(Mux *mux, void **vp)
 {
-	return _drawrecv(mux, 1);
+	return _drawrecv(mux, 0, vp);
 }
 
 static int
blob - 1da3fb3987e90271dbb173b81b09e2051a462597
blob + 101aa374475de763bbbb8a886c5cd0a575569740
--- src/libdraw/event.c
+++ src/libdraw/event.c
@@ -214,10 +214,14 @@ static int
 finishrpc(Muxrpc *r, Wsysmsg *w)
 {
 	uchar *p;
+	void *v;
 	int n;
 	
-	if((p = muxrpccanfinish(r)) == nil)
+	if(!muxrpccanfinish(r, &v))
 		return 0;
+	p = v;
+	if(p == nil)	/* eof on connection */
+		exit(0);
 	GET(p, n);
 	convM2W(p, n, w);
 	free(p);
@@ -269,6 +273,9 @@ extract(int canblock)
 			if(eslave[i].rpc == nil)
 				eslave[i].rpc = startrpc(Trdmouse);
 			if(eslave[i].rpc){
+				/* if ready, don't block in select */
+				if(eslave[i].rpc->p)
+					canblock = 0;
 				FD_SET(display->srvfd, &rset);
 				FD_SET(display->srvfd, &xset);
 				if(display->srvfd > max)
@@ -278,6 +285,9 @@ extract(int canblock)
 			if(eslave[i].rpc == nil)
 				eslave[i].rpc = startrpc(Trdkbd);
 			if(eslave[i].rpc){
+				/* if ready, don't block in select */
+				if(eslave[i].rpc->p)
+					canblock = 0;
 				FD_SET(display->srvfd, &rset);
 				FD_SET(display->srvfd, &xset);
 				if(display->srvfd > max)
blob - 4a89ca22a72bd0c27c2ea207a5012e908b819fb2
blob + d9d9d8a6283ef25f6bb54deddb79886c03d1c8ba
--- src/libmux/io.c
+++ src/libmux/io.c
@@ -34,7 +34,7 @@ _muxrecvproc(void *v)
 	qunlock(&mux->inlk);
 	qlock(&mux->lk);
 	_muxqhangup(q);
-	while((p = _muxnbqrecv(q)) != nil)
+	while(_muxnbqrecv(q, &p))
 		free(p);
 	free(q);
 	mux->readq = nil;
@@ -64,7 +64,7 @@ _muxsendproc(void *v)
 	qunlock(&mux->outlk);
 	qlock(&mux->lk);
 	_muxqhangup(q);
-	while((p = _muxnbqrecv(q)) != nil)
+	while(_muxnbqrecv(q, &p))
 		free(p);
 	free(q);
 	mux->writeq = nil;
@@ -73,42 +73,39 @@ _muxsendproc(void *v)
 	return;
 }
 
-void*
-_muxrecv(Mux *mux, int canblock)
+int
+_muxrecv(Mux *mux, int canblock, void **vp)
 {
 	void *p;
+	int ret;
 
 	qlock(&mux->lk);
-/*
-	if(mux->state != VtStateConnected){
-		werrstr("not connected");
-		qunlock(&mux->lk);
-		return nil;
-	}
-*/
 	if(mux->readq){
 		qunlock(&mux->lk);
-		if(canblock)
-			return _muxqrecv(mux->readq);
-		return _muxnbqrecv(mux->readq);
+		if(canblock){
+			*vp = _muxqrecv(mux->readq);
+			return 1;
+		}
+		return _muxnbqrecv(mux->readq, vp);
 	}
 
 	qlock(&mux->inlk);
 	qunlock(&mux->lk);
-	if(canblock)
+	if(canblock){
 		p = mux->recv(mux);
-	else{
+		ret = 1;
+	}else{
 		if(mux->nbrecv)
-			p = mux->nbrecv(mux);
-		else
+			ret = mux->nbrecv(mux, &p);
+		else{
+			/* send eof, not "no packet ready" */
 			p = nil;
+			ret = 1;
+		}
 	}
 	qunlock(&mux->inlk);
-/*
-	if(!p && canblock)
-		vthangup(mux);
-*/
-	return p;
+	*vp = p;
+	return ret;
 }
 
 int
blob - bfabb23890aab5bddab4123c80d2f72dd3e4009f
blob + 8257fb0e7200fc947ade5b2832f97f5b8507ad39
--- src/libmux/mux.c
+++ src/libmux/mux.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Russ Cox, Massachusetts Institute of Technology */
+/* Copyright (C) 2003-2006 Russ Cox, Massachusetts Institute of Technology */
 /* See COPYRIGHT */
 
 /*
@@ -100,12 +100,17 @@ muxmsgandqlock(Mux *mux, void *p)
 void
 electmuxer(Mux *mux)
 {
+	Muxrpc *rpc;
+
 	/* if there is anyone else sleeping, wake them to mux */
-	if(mux->sleep.next != &mux->sleep){
-		mux->muxer = mux->sleep.next;
-		rwakeup(&mux->muxer->r);
-	}else
-		mux->muxer = nil;
+	for(rpc=mux->sleep.next; rpc != &mux->sleep; rpc = rpc->next){
+		if(!rpc->async){
+			mux->muxer = rpc;
+			rwakeup(&rpc->r);
+			return;
+		}
+	}
+	mux->muxer = nil;
 }
 
 void*
@@ -133,7 +138,7 @@ muxrpc(Mux *mux, void *tx)
 		mux->muxer = r;
 		while(!r->p){
 			qunlock(&mux->lk);
-			p = _muxrecv(mux, 1);
+			_muxrecv(mux, 1, &p);
 			if(p == nil){
 				/* eof -- just give up and pass the buck */
 				qlock(&mux->lk);
@@ -144,7 +149,6 @@ muxrpc(Mux *mux, void *tx)
 		}
 		electmuxer(mux);
 	}
-/*print("finished %p\n", r); */
 	p = r->p;
 	puttag(mux, r);
 	qunlock(&mux->lk);
@@ -161,24 +165,29 @@ muxrpcstart(Mux *mux, void *tx)
 
 	if((r = allocmuxrpc(mux)) == nil)
 		return nil;
+	r->async = 1;
 	if((tag = tagmuxrpc(r, tx)) < 0)
 		return nil;
 	return r;
 }
 
-void*
-muxrpccanfinish(Muxrpc *r)
+int
+muxrpccanfinish(Muxrpc *r, void **vp)
 {
-	char *p;
+	void *p;
 	Mux *mux;
-	
+	int ret;
+
 	mux = r->mux;
 	qlock(&mux->lk);
+	ret = 1;
 	if(!r->p && !mux->muxer){
 		mux->muxer = r;
 		while(!r->p){
 			qunlock(&mux->lk);
-			p = _muxrecv(mux, 0);
+			p = nil;
+			if(!_muxrecv(mux, 0, &p))
+				ret = 0;
 			if(p == nil){
 				qlock(&mux->lk);
 				break;
@@ -191,7 +200,8 @@ muxrpccanfinish(Muxrpc *r)
 	if(p)
 		puttag(mux, r);
 	qunlock(&mux->lk);
-	return p;
+	*vp = p;
+	return ret;
 }
 
 static void
blob - 1cadbe6c2c1039822f39fc9a1dbd9406295f1de5
blob + 2151c2529da550e97ca61c57c8708d7d0a400c15
--- src/libmux/queue.c
+++ src/libmux/queue.c
@@ -81,8 +81,8 @@ _muxqrecv(Muxqueue *q)
 	return p;
 }
 
-void*
-_muxnbqrecv(Muxqueue *q)
+int
+_muxnbqrecv(Muxqueue *q, void **vp)
 {
 	void *p;
 	Qel *e;
@@ -90,14 +90,16 @@ _muxnbqrecv(Muxqueue *q)
 	qlock(&q->lk);
 	if(q->head == nil){
 		qunlock(&q->lk);
-		return nil;
+		*vp = nil;
+		return q->hungup;
 	}
 	e = q->head;
 	q->head = e->next;
 	qunlock(&q->lk);
 	p = e->p;
 	free(e);
-	return p;
+	*vp = p;
+	return 1;
 }
 
 void