170 lines · 2.3 KB · C
RawDownload
#include <u.h>#include <libc.h>#include "cec.h" typedef struct {	char	type;	Pkt	p;} Muxmsg; #define	Muxo	(offsetof(Muxmsg, p)) typedef struct {	int	fd;	int	type;	int	pid;} Muxproc; struct Mux {	Muxmsg	m;	Muxproc	p[2];	int	pfd[2];	int	inuse;	int	to;	int	retries;	int	step;	vlong	t0;	vlong	t1;}; static Mux smux = {.inuse	= -1,}; voidmuxcec(int, int cfd){	Muxmsg m;	int l; 	m.type = Fcec;	while((l = netget(&m.p, sizeof m.p)) > 0)		if(write(cfd, &m, l+Muxo) != l+Muxo)			break;	exits("");} voidmuxkbd(int kfd, int cfd){	Muxmsg m;	int o; 	m.type = Fkbd;	o = offsetof(Muxmsg, p.data[0]);	while((m.p.len = read(kfd, m.p.data, sizeof m.p.data)) > 0)		if(write(cfd, &m, o+m.p.len) != o+m.p.len)			break;	m.type = Ffatal;	write(cfd, &m, 4);	exits("");} intmuxproc(Mux *m, Muxproc *p, int fd, void (*f)(int, int), int type){	memset(p, 0, sizeof p);	p->type = -1;	switch(p->pid = rfork(RFPROC|RFFDG)){	case -1:		return -1;	case 0:		close(m->pfd[0]);		f(fd, m->pfd[1]);	default:		p->fd = fd;		p->type = type;		return p->pid;	}} voidmuxfree(Mux *m){	close(m->pfd[0]);	close(m->pfd[1]);	postnote(PNPROC, m->p[0].pid, "this note goes to 11");	postnote(PNPROC, m->p[1].pid, "this note goes to 11");	waitpid();	waitpid();	memset(m, 0, sizeof *m);	m->inuse = -1;} Mux*mux(int fd[2]){	Mux *m; 	if(smux.inuse != -1)		sysfatal("mux in use");	m = &smux;	m->inuse = 1;	if(pipe(m->pfd) == -1)		sysfatal("pipe: %r");	muxproc(m, m->p+0, fd[0], muxkbd, Fkbd);	muxproc(m, m->p+1, fd[1], muxcec, Fcec);	close(m->pfd[1]);	return m;} #define MSEC()	(nsec()/1000000) static voidtimestamp(Mux *m){	m->t0 = MSEC();} inttimeout(Mux *m){	vlong t; 	if(m->to == 0)		return -1;	t = m->t0 + m->step;	if(t > m->t1)		t = m->t1;	t -= MSEC();	if(t < 5)		t = 0;	return t;} intmuxread(Mux *m, Pkt *p){	int r, t; 	t = timeout(m);	r = -1;	if(t != 0){		if(t > 0)			alarm(t);		r = read(m->pfd[0], &m->m, sizeof m->m);		if(t > 0)			alarm(0);	}	if(r == -1){		timestamp(m);		if(m->t0 + 5 >= m->t1)			return Ftimedout;		m->retries++;		if(m->step < 1000)			m->step <<= 1;		return Ftimeout;	}	memcpy(p, &m->m.p, r-Muxo);	return m->m.type;} voidmuxtimeout(Mux *m, int to){	m->retries = 0;	timestamp(m);	m->step = 75;	m->to = to;	m->t1 = m->t0 + to;}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t