commit - 201e19d672a2dab81e213237569022607aced2e1
commit + 880ab2f10a2d4922d314ff8d016ea078f3c7f019
blob - 4d8d3cdf49b1c9f79ceceb889fc35fd87b09e4cf
blob + 87d4e7b0f45338983d8c2274ecac9d1f5735ca93
--- src/cmd/acme/mail/dat.h
+++ src/cmd/acme/mail/dat.h
struct Window
{
+ /* coordinate wineventproc and window thread */
+ QLock lk;
+ int ref;
+
/* file descriptors */
CFid* ctl;
CFid* event;
extern char* winreadbody(Window*, int*);
extern void windormant(Window*);
extern void winsetdump(Window*, char*, char*);
+extern void winincref(Window*);
+extern void windecref(Window*);
extern void readmbox(Message*, char*, char*);
extern void rewritembox(Window*, Message*);
blob - ac74b63423f446d9183c40950dc99905d7e16871
blob + f8030ca4f8251f08744ad7fb424c864614c6c234
--- src/cmd/acme/mail/mail.c
+++ src/cmd/acme/mail/mail.c
char *s, *t, *buf;
w = v;
+ winincref(w);
proccreate(wineventproc, w, STACK);
for(;;){
blob - 9c4e0bb4aab4cd928d303657682d967a38fdbbfc
blob + 9406b7993d5a43f3ed09c6c7d07f6cba49bd6da6
--- src/cmd/acme/mail/mesg.c
+++ src/cmd/acme/mail/mesg.c
}
if(strcmp(args[0], "Del") == 0){
if(windel(m->w, 0)){
- chanfree(m->w->cevent);
- free(m->w);
+ windecref(m->w);
m->w = nil;
if(m->isreply)
delreply(m);
m = v;
w = m->w;
threadsetname("mesgctl");
+ winincref(w);
proccreate(wineventproc, w, STACK);
for(;;){
e = recvp(w->cevent);
blob - e407b0c3ade40e29b87c021b32773bc79fd2e9c4
blob + 8a3e60a90eacc7c8361ad830dc377cf9cc7473a5
--- src/cmd/acme/mail/win.c
+++ src/cmd/acme/mail/win.c
w->body = nil;
w->data = nil;
w->cevent = chancreate(sizeof(Event*), 0);
+ w->ref = 1;
return w;
}
void
+winincref(Window *w)
+{
+ qlock(&w->lk);
+ ++w->ref;
+ qunlock(&w->lk);
+}
+
+void
+windecref(Window *w)
+{
+ qlock(&w->lk);
+ if(--w->ref > 0){
+ qunlock(&w->lk);
+ return;
+ }
+ fsclose(w->event);
+ chanfree(w->cevent);
+ free(w);
+}
+
+void
winsetdump(Window *w, char *dir, char *cmd)
{
if(dir != nil)
w->nbuf = fsread(w->event, w->buf, sizeof w->buf);
if(w->nbuf <= 0){
/* probably because window has exited, and only called by wineventproc, so just shut down */
+ windecref(w);
threadexits(nil);
}
w->bufp = w->buf;
windormant(w);
fsclose(w->ctl);
w->ctl = nil;
- fsclose(w->event);
- w->event = nil;
return 1;
}