From 880ab2f10a2d4922d314ff8d016ea078f3c7f019 Mon Sep 17 00:00:00 2001 From: rsc Date: Wed, 15 Feb 2006 23:06:27 +0000 Subject: fixed --- src/cmd/acme/mail/dat.h | 6 ++++++ src/cmd/acme/mail/mail.c | 1 + src/cmd/acme/mail/mesg.c | 4 ++-- src/cmd/acme/mail/win.c | 25 +++++++++++++++++++++++-- 4 files changed, 32 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/cmd/acme/mail/dat.h b/src/cmd/acme/mail/dat.h index 4d8d3cdf..87d4e7b0 100644 --- a/src/cmd/acme/mail/dat.h +++ b/src/cmd/acme/mail/dat.h @@ -25,6 +25,10 @@ struct Event struct Window { + /* coordinate wineventproc and window thread */ + QLock lk; + int ref; + /* file descriptors */ CFid* ctl; CFid* event; @@ -112,6 +116,8 @@ extern int winsetaddr(Window*, char*, int); 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*); diff --git a/src/cmd/acme/mail/mail.c b/src/cmd/acme/mail/mail.c index ac74b634..f8030ca4 100644 --- a/src/cmd/acme/mail/mail.c +++ b/src/cmd/acme/mail/mail.c @@ -470,6 +470,7 @@ mainctl(void *v) char *s, *t, *buf; w = v; + winincref(w); proccreate(wineventproc, w, STACK); for(;;){ diff --git a/src/cmd/acme/mail/mesg.c b/src/cmd/acme/mail/mesg.c index 9c4e0bb4..9406b799 100644 --- a/src/cmd/acme/mail/mesg.c +++ b/src/cmd/acme/mail/mesg.c @@ -720,8 +720,7 @@ mesgcommand(Message *m, char *cmd) } 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); @@ -886,6 +885,7 @@ mesgctl(void *v) m = v; w = m->w; threadsetname("mesgctl"); + winincref(w); proccreate(wineventproc, w, STACK); for(;;){ e = recvp(w->cevent); diff --git a/src/cmd/acme/mail/win.c b/src/cmd/acme/mail/win.c index e407b0c3..8a3e60a9 100644 --- a/src/cmd/acme/mail/win.c +++ b/src/cmd/acme/mail/win.c @@ -24,9 +24,31 @@ newwindow(void) 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) { @@ -125,6 +147,7 @@ wingetec(Window *w) 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; @@ -255,8 +278,6 @@ windel(Window *w, int sure) windormant(w); fsclose(w->ctl); w->ctl = nil; - fsclose(w->event); - w->event = nil; return 1; } -- cgit v1.2.3