ref: 4b194ca0e86b5594bf4df1d1ee743c1965592c9c
parent: 545506fbfe7f6558a29e0182a9ac7771a13f17ff
author: glenda <glenda@cirno>
date: Sun Oct 2 19:14:14 EDT 2011
libdraw: shutdown keyboard and mouseprocs with threadint, libthread: avoid delayed note leak (this fixes the "too many delayed notes" error with auth/fgui)
--- a/sys/src/libdraw/keyboard.c
+++ b/sys/src/libdraw/keyboard.c
@@ -4,26 +4,15 @@
#include <thread.h>
#include <keyboard.h>
-
void
closekeyboard(Keyboardctl *kc)
{if(kc == nil)
return;
-
- postnote(PNPROC, kc->pid, "kill");
-
-#ifdef BUG
- /* Drain the channel */
- while(?kc->c)
- <-kc->c;
-#endif
-
close(kc->ctlfd);
close(kc->consfd);
- free(kc->file);
- free(kc->c);
- free(kc);
+ kc->consfd = kc->ctlfd = -1;
+ threadint(kc->pid);
}
static
@@ -37,23 +26,23 @@
kc = arg;
threadsetname("kbdproc");- kc->pid = getpid();
n = 0;
- for(;;){+loop:
+ while(kc->consfd >= 0){ while(n>0 && fullrune(buf, n)){m = chartorune(&r, buf);
n -= m;
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;
}
+ chanfree(kc->c);
+ free(kc->file);
+ free(kc);
}
Keyboardctl*
@@ -91,7 +80,7 @@
}
free(t);
kc->c = chancreate(sizeof(Rune), 20);
- proccreate(_ioproc, kc, 4096);
+ kc->pid = proccreate(_ioproc, kc, 4096);
return kc;
}
--- a/sys/src/libdraw/mouse.c
+++ b/sys/src/libdraw/mouse.c
@@ -17,17 +17,10 @@
{if(mc == nil)
return;
-
- postnote(PNPROC, mc->pid, "kill");
-
- do; while(nbrecv(mc->c, &mc->Mouse) > 0);
-
close(mc->mfd);
close(mc->cfd);
- free(mc->file);
- free(mc->c);
- free(mc->resizec);
- free(mc);
+ mc->mfd = mc->cfd = -1;
+ threadint(mc->pid);
}
int
@@ -46,7 +39,7 @@
void
_ioproc(void *arg)
{- int n, nerr, one;
+ int n, one;
char buf[1+5*12];
Mouse m;
Mousectl *mc;
@@ -55,21 +48,15 @@
threadsetname("mouseproc");one = 1;
memset(&m, 0, sizeof m);
- mc->pid = getpid();
- nerr = 0;
- for(;;){+loop:
+ while(mc->mfd >= 0){n = read(mc->mfd, buf, sizeof buf);
- if(n != 1+4*12){- yield(); /* if error is due to exiting, we'll exit here */
- fprint(2, "mouse: bad count %d not 49: %r\n", n);
- if(n<0 || ++nerr>10)
- threadexits("read error");- continue;
- }
- nerr = 0;
+ if(n != 1+4*12)
+ goto loop;
switch(buf[0]){case 'r':
- send(mc->resizec, &one);
+ if(send(mc->resizec, &one) < 0)
+ goto loop;
/* fall through */
case 'm':
m.xy.x = atoi(buf+1+0*12);
@@ -76,7 +63,8 @@
m.xy.y = atoi(buf+1+1*12);
m.buttons = atoi(buf+1+2*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.
* This means that programs should receive into mc->Mouse (see readmouse() above) if
@@ -86,6 +74,10 @@
break;
}
}
+ free(mc->file);
+ chanfree(mc->c);
+ chanfree(mc->resizec);
+ free(mc);
}
Mousectl*
@@ -124,7 +116,7 @@
mc->image = i;
mc->c = chancreate(sizeof(Mouse), 0);
mc->resizec = chancreate(sizeof(int), 2);
- proccreate(_ioproc, mc, 4096);
+ mc->pid = proccreate(_ioproc, mc, 4096);
return mc;
}
--- a/sys/src/libthread/note.c
+++ b/sys/src/libthread/note.c
@@ -52,6 +52,7 @@
{int i;
Note *n;
+ char s[ERRMAX];
int (*fn)(void*, char*);
if(!p->pending)
@@ -60,10 +61,14 @@
p->pending = 0;
for(n=notes; n<enotes; n++){ if(n->proc == p){+ strcpy(s, n->s);
+ n->proc = nil;
+ unlock(&n->inuse);
+
for(i=0; i<NFN; i++){if(onnotepid[i]!=p->pid || (fn = onnote[i])==nil)
continue;
- if((*fn)(v, n->s))
+ if((*fn)(v, s))
break;
}
if(i==NFN){@@ -74,8 +79,6 @@
abort();
threadexitsall(n->s);
}
- n->proc = nil;
- unlock(&n->inuse);
}
}
}
--
⑨