libdraw: shutdown keyboard and mouseprocs with threadint, libthread: avoid delayed note leak (this fixes the "too many delayed notes" error with auth/fgui)

glenda 2011-10-02 23:14:14 +02:00
parent b8d741d34b
commit da4d5c9c21
3 changed files with 34 additions and 50 deletions

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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);
} }
} }
} }