libdraw: shutdown keyboard and mouseprocs with threadint, libthread: avoid delayed note leak (this fixes the "too many delayed notes" error with auth/fgui)
parent
b8d741d34b
commit
da4d5c9c21
|
@ -4,26 +4,15 @@
|
||||||
#include <thread.h>
|
#include <thread.h>
|
||||||
#include <keyboard.h>
|
#include <keyboard.h>
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
closekeyboard(Keyboardctl *kc)
|
closekeyboard(Keyboardctl *kc)
|
||||||
{
|
{
|
||||||
if(kc == nil)
|
if(kc == nil)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
postnote(PNPROC, kc->pid, "kill");
|
|
||||||
|
|
||||||
#ifdef BUG
|
|
||||||
/* Drain the channel */
|
|
||||||
while(?kc->c)
|
|
||||||
<-kc->c;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
close(kc->ctlfd);
|
close(kc->ctlfd);
|
||||||
close(kc->consfd);
|
close(kc->consfd);
|
||||||
free(kc->file);
|
kc->consfd = kc->ctlfd = -1;
|
||||||
free(kc->c);
|
threadint(kc->pid);
|
||||||
free(kc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -37,23 +26,23 @@ _ioproc(void *arg)
|
||||||
|
|
||||||
kc = arg;
|
kc = arg;
|
||||||
threadsetname("kbdproc");
|
threadsetname("kbdproc");
|
||||||
kc->pid = getpid();
|
|
||||||
n = 0;
|
n = 0;
|
||||||
for(;;){
|
loop:
|
||||||
|
while(kc->consfd >= 0){
|
||||||
while(n>0 && fullrune(buf, n)){
|
while(n>0 && fullrune(buf, n)){
|
||||||
m = chartorune(&r, buf);
|
m = chartorune(&r, buf);
|
||||||
n -= m;
|
n -= m;
|
||||||
memmove(buf, buf+m, n);
|
memmove(buf, buf+m, n);
|
||||||
send(kc->c, &r);
|
if(send(kc->c, &r) < 0)
|
||||||
}
|
goto loop;
|
||||||
m = read(kc->consfd, buf+n, sizeof buf-n);
|
|
||||||
if(m <= 0){
|
|
||||||
yield(); /* if error is due to exiting, we'll exit here */
|
|
||||||
fprint(2, "keyboard read error: %r\n");
|
|
||||||
threadexits("error");
|
|
||||||
}
|
}
|
||||||
|
if((m = read(kc->consfd, buf+n, sizeof buf-n)) <= 0)
|
||||||
|
goto loop;
|
||||||
n += m;
|
n += m;
|
||||||
}
|
}
|
||||||
|
chanfree(kc->c);
|
||||||
|
free(kc->file);
|
||||||
|
free(kc);
|
||||||
}
|
}
|
||||||
|
|
||||||
Keyboardctl*
|
Keyboardctl*
|
||||||
|
@ -91,7 +80,7 @@ Error2:
|
||||||
}
|
}
|
||||||
free(t);
|
free(t);
|
||||||
kc->c = chancreate(sizeof(Rune), 20);
|
kc->c = chancreate(sizeof(Rune), 20);
|
||||||
proccreate(_ioproc, kc, 4096);
|
kc->pid = proccreate(_ioproc, kc, 4096);
|
||||||
return kc;
|
return kc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,17 +17,10 @@ closemouse(Mousectl *mc)
|
||||||
{
|
{
|
||||||
if(mc == nil)
|
if(mc == nil)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
postnote(PNPROC, mc->pid, "kill");
|
|
||||||
|
|
||||||
do; while(nbrecv(mc->c, &mc->Mouse) > 0);
|
|
||||||
|
|
||||||
close(mc->mfd);
|
close(mc->mfd);
|
||||||
close(mc->cfd);
|
close(mc->cfd);
|
||||||
free(mc->file);
|
mc->mfd = mc->cfd = -1;
|
||||||
free(mc->c);
|
threadint(mc->pid);
|
||||||
free(mc->resizec);
|
|
||||||
free(mc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -46,7 +39,7 @@ static
|
||||||
void
|
void
|
||||||
_ioproc(void *arg)
|
_ioproc(void *arg)
|
||||||
{
|
{
|
||||||
int n, nerr, one;
|
int n, one;
|
||||||
char buf[1+5*12];
|
char buf[1+5*12];
|
||||||
Mouse m;
|
Mouse m;
|
||||||
Mousectl *mc;
|
Mousectl *mc;
|
||||||
|
@ -55,28 +48,23 @@ _ioproc(void *arg)
|
||||||
threadsetname("mouseproc");
|
threadsetname("mouseproc");
|
||||||
one = 1;
|
one = 1;
|
||||||
memset(&m, 0, sizeof m);
|
memset(&m, 0, sizeof m);
|
||||||
mc->pid = getpid();
|
loop:
|
||||||
nerr = 0;
|
while(mc->mfd >= 0){
|
||||||
for(;;){
|
|
||||||
n = read(mc->mfd, buf, sizeof buf);
|
n = read(mc->mfd, buf, sizeof buf);
|
||||||
if(n != 1+4*12){
|
if(n != 1+4*12)
|
||||||
yield(); /* if error is due to exiting, we'll exit here */
|
goto loop;
|
||||||
fprint(2, "mouse: bad count %d not 49: %r\n", n);
|
|
||||||
if(n<0 || ++nerr>10)
|
|
||||||
threadexits("read error");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
nerr = 0;
|
|
||||||
switch(buf[0]){
|
switch(buf[0]){
|
||||||
case 'r':
|
case 'r':
|
||||||
send(mc->resizec, &one);
|
if(send(mc->resizec, &one) < 0)
|
||||||
|
goto loop;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case 'm':
|
case 'm':
|
||||||
m.xy.x = atoi(buf+1+0*12);
|
m.xy.x = atoi(buf+1+0*12);
|
||||||
m.xy.y = atoi(buf+1+1*12);
|
m.xy.y = atoi(buf+1+1*12);
|
||||||
m.buttons = atoi(buf+1+2*12);
|
m.buttons = atoi(buf+1+2*12);
|
||||||
m.msec = atoi(buf+1+3*12);
|
m.msec = atoi(buf+1+3*12);
|
||||||
send(mc->c, &m);
|
if(send(mc->c, &m) < 0)
|
||||||
|
goto loop;
|
||||||
/*
|
/*
|
||||||
* mc->Mouse is updated after send so it doesn't have wrong value if we block during send.
|
* mc->Mouse is updated after send so it doesn't have wrong value if we block during send.
|
||||||
* This means that programs should receive into mc->Mouse (see readmouse() above) if
|
* This means that programs should receive into mc->Mouse (see readmouse() above) if
|
||||||
|
@ -86,6 +74,10 @@ _ioproc(void *arg)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free(mc->file);
|
||||||
|
chanfree(mc->c);
|
||||||
|
chanfree(mc->resizec);
|
||||||
|
free(mc);
|
||||||
}
|
}
|
||||||
|
|
||||||
Mousectl*
|
Mousectl*
|
||||||
|
@ -124,7 +116,7 @@ initmouse(char *file, Image *i)
|
||||||
mc->image = i;
|
mc->image = i;
|
||||||
mc->c = chancreate(sizeof(Mouse), 0);
|
mc->c = chancreate(sizeof(Mouse), 0);
|
||||||
mc->resizec = chancreate(sizeof(int), 2);
|
mc->resizec = chancreate(sizeof(int), 2);
|
||||||
proccreate(_ioproc, mc, 4096);
|
mc->pid = proccreate(_ioproc, mc, 4096);
|
||||||
return mc;
|
return mc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ delayednotes(Proc *p, void *v)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
Note *n;
|
Note *n;
|
||||||
|
char s[ERRMAX];
|
||||||
int (*fn)(void*, char*);
|
int (*fn)(void*, char*);
|
||||||
|
|
||||||
if(!p->pending)
|
if(!p->pending)
|
||||||
|
@ -60,10 +61,14 @@ delayednotes(Proc *p, void *v)
|
||||||
p->pending = 0;
|
p->pending = 0;
|
||||||
for(n=notes; n<enotes; n++){
|
for(n=notes; n<enotes; n++){
|
||||||
if(n->proc == p){
|
if(n->proc == p){
|
||||||
|
strcpy(s, n->s);
|
||||||
|
n->proc = nil;
|
||||||
|
unlock(&n->inuse);
|
||||||
|
|
||||||
for(i=0; i<NFN; i++){
|
for(i=0; i<NFN; i++){
|
||||||
if(onnotepid[i]!=p->pid || (fn = onnote[i])==nil)
|
if(onnotepid[i]!=p->pid || (fn = onnote[i])==nil)
|
||||||
continue;
|
continue;
|
||||||
if((*fn)(v, n->s))
|
if((*fn)(v, s))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(i==NFN){
|
if(i==NFN){
|
||||||
|
@ -74,8 +79,6 @@ delayednotes(Proc *p, void *v)
|
||||||
abort();
|
abort();
|
||||||
threadexitsall(n->s);
|
threadexitsall(n->s);
|
||||||
}
|
}
|
||||||
n->proc = nil;
|
|
||||||
unlock(&n->inuse);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue