distinguish between "cannot receive without blocking" and "EOF on connection". In libmux, do not elect async guys muxers, so that synchronous RPC calls run in the main event loop (e.g., in eresized) do not get stuck. Fixes problem reported by Lu Xuxiao, namely that jpg etc. would spin at 100% cpu usage.
112 lines
1.4 KiB
C
112 lines
1.4 KiB
C
/* Copyright (C) 2003 Russ Cox, Massachusetts Institute of Technology */
|
|
/* See COPYRIGHT */
|
|
|
|
#include <u.h>
|
|
#include <libc.h>
|
|
#include <mux.h>
|
|
|
|
typedef struct Qel Qel;
|
|
struct Qel
|
|
{
|
|
Qel *next;
|
|
void *p;
|
|
};
|
|
|
|
struct Muxqueue
|
|
{
|
|
int hungup;
|
|
QLock lk;
|
|
Rendez r;
|
|
Qel *head;
|
|
Qel *tail;
|
|
};
|
|
|
|
Muxqueue*
|
|
_muxqalloc(void)
|
|
{
|
|
Muxqueue *q;
|
|
|
|
q = mallocz(sizeof(Muxqueue), 1);
|
|
if(q == nil)
|
|
return nil;
|
|
q->r.l = &q->lk;
|
|
return q;
|
|
}
|
|
|
|
int
|
|
_muxqsend(Muxqueue *q, void *p)
|
|
{
|
|
Qel *e;
|
|
|
|
e = malloc(sizeof(Qel));
|
|
if(e == nil)
|
|
return -1;
|
|
qlock(&q->lk);
|
|
if(q->hungup){
|
|
werrstr("hungup queue");
|
|
qunlock(&q->lk);
|
|
free(e);
|
|
return -1;
|
|
}
|
|
e->p = p;
|
|
e->next = nil;
|
|
if(q->head == nil)
|
|
q->head = e;
|
|
else
|
|
q->tail->next = e;
|
|
q->tail = e;
|
|
rwakeup(&q->r);
|
|
qunlock(&q->lk);
|
|
return 0;
|
|
}
|
|
|
|
void*
|
|
_muxqrecv(Muxqueue *q)
|
|
{
|
|
void *p;
|
|
Qel *e;
|
|
|
|
qlock(&q->lk);
|
|
while(q->head == nil && !q->hungup)
|
|
rsleep(&q->r);
|
|
if(q->hungup){
|
|
qunlock(&q->lk);
|
|
return nil;
|
|
}
|
|
e = q->head;
|
|
q->head = e->next;
|
|
qunlock(&q->lk);
|
|
p = e->p;
|
|
free(e);
|
|
return p;
|
|
}
|
|
|
|
int
|
|
_muxnbqrecv(Muxqueue *q, void **vp)
|
|
{
|
|
void *p;
|
|
Qel *e;
|
|
|
|
qlock(&q->lk);
|
|
if(q->head == nil){
|
|
qunlock(&q->lk);
|
|
*vp = nil;
|
|
return q->hungup;
|
|
}
|
|
e = q->head;
|
|
q->head = e->next;
|
|
qunlock(&q->lk);
|
|
p = e->p;
|
|
free(e);
|
|
*vp = p;
|
|
return 1;
|
|
}
|
|
|
|
void
|
|
_muxqhangup(Muxqueue *q)
|
|
{
|
|
qlock(&q->lk);
|
|
q->hungup = 1;
|
|
rwakeupall(&q->r);
|
|
qunlock(&q->lk);
|
|
}
|