commit - d3864abaee496db2f97dff1dbf5c7766d4439c7b
commit + 3a19470202c5c0f6e9375e5d57535c3d508f2edf
blob - 53321fa5258886698e48b24b585ab427bfaf3f4b
blob + e9890fc31c8fbd67357a23e68bb855e64292095b
--- include/mux.h
+++ include/mux.h
uint tag;
void *p;
int waiting;
+ int async;
};
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 */
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
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
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);
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
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);
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)
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
qunlock(&mux->inlk);
qlock(&mux->lk);
_muxqhangup(q);
- while((p = _muxnbqrecv(q)) != nil)
+ while(_muxnbqrecv(q, &p))
free(p);
free(q);
mux->readq = nil;
qunlock(&mux->outlk);
qlock(&mux->lk);
_muxqhangup(q);
- while((p = _muxnbqrecv(q)) != nil)
+ while(_muxnbqrecv(q, &p))
free(p);
free(q);
mux->writeq = nil;
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
-/* Copyright (C) 2003 Russ Cox, Massachusetts Institute of Technology */
+/* Copyright (C) 2003-2006 Russ Cox, Massachusetts Institute of Technology */
/* See COPYRIGHT */
/*
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*
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);
}
electmuxer(mux);
}
-/*print("finished %p\n", r); */
p = r->p;
puttag(mux, r);
qunlock(&mux->lk);
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;
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
return p;
}
-void*
-_muxnbqrecv(Muxqueue *q)
+int
+_muxnbqrecv(Muxqueue *q, void **vp)
{
void *p;
Qel *e;
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