From mboxrd@z Thu Jan 1 00:00:00 1970 Message-Id: <200509212234.j8LMYrG01220@zamenhof.cs.utwente.nl> To: Russ Cox , Fans of the OS Plan 9 from Bell Labs <9fans@cse.psu.edu> Subject: Re: [9fans] thread confusion In-reply-to: Your message of "Wed, 21 Sep 2005 16:37:21 -0400." References: <2e4165d0a4172357099de271ac66cd5e@lsub.org> <200509211505.j8LF5FQ00275@zamenhof.cs.utwente.nl> <200509212025.j8LKPdr29497@demeter.cs.utwente.nl> From: Axel Belinfante MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0" Content-ID: <1217.1127341986.0@zamenhof.cs.utwente.nl.cs.utwente.nl> Date: Thu, 22 Sep 2005 00:34:53 +0200 Cc: Topicbox-Message-UUID: 8e892562-ead0-11e9-9d60-3106f5b1d025 ------- =_aaaaaaaaaa0 Content-Type: text/plain; charset="us-ascii" Content-ID: <1217.1127341986.1@zamenhof.cs.utwente.nl.cs.utwente.nl> > Again, it sounds like you're > not closing all the references to one end of the pipe. > If multiple programs have references to a pipe end, > they *all* need to close them. Make sure that the > proc running tlsClient doesn't have a reference too. Just checking: I assume by 'references' you mean file descriptors in the process' fd table? ehm... I just realized: I create the procs with proccreate, so all procs share the same references, and when I close them in the main proc, they go away in the other ones as well, or so it seems, at least according to cat /proc/*/fd. nevertheless, without the zero-write before one of the closes they just keep hanging in the read, even when their fd table no longer shows the pipe file descriptors in any of the fd tables. If I don't share the fd table, and just give each of the sub processes their own end of the pipe, I'll never be able to close those from within those processes, because they are both locked up in a read (essentially waiting for each other). I have attached a silly program. Axel. ------- =_aaaaaaaaaa0 Content-Type: text/plain; charset="us-ascii" Content-ID: <1217.1127341986.2@zamenhof.cs.utwente.nl.cs.utwente.nl> #include #include #include enum { STACK = 16*2048, }; typedef struct State { int id; int fd, tobeclosed; Channel *c; } State; static void subproc(void *arg) { State *m; char buf[1024]; int n; m = arg; print("subproc tid=%d tobeclosed=%d\n", threadid(), m->tobeclosed); sleep(15000); // print(" subproc tid=%d pid=%d\n", m->id, threadpid(m->id)); // close(m->tobeclosed); // sleep(15000); print("subproc writing fd=%d n=%d\n", m->fd, n); n = write(m->fd, buf, 5); print("subproc written fd=%d n=%d\n", m->fd, n); while((n = read(m->fd, buf, sizeof(buf))) > 0) print("subproc fd=%d] read n=%d\n", m->fd, n); print("subproc eof fd=%d n=%d\n", m->fd, n); sleep(15000); sendul(m->c, 0); print("exiting subproc tid=%d pid=%d\n", m->id, threadpid(m->id)); threadexits(nil); } static void mainproc(void *arg) { State *m; char buf[1024]; int n; m = arg; print("mainproc tid=%d tobeclosed=%d\n", threadid(), m->tobeclosed); sleep(15000); // print(" mainproc tid=%d pid=%d\n", m->id, threadpid(m->id)); // close(m->tobeclosed); // sleep(15000); print("mainproc writing fd=%d n=%d\n", m->fd, n); n = write(m->fd, buf, 7); print("mainproc written fd=%d n=%d\n", m->fd, n); while((n = read(m->fd, buf, sizeof(buf))) > 0) print("mainproc fd=%d n=%d\n", m->fd, n); print("mainproc fd=%d eof n=%d\n", m->fd, n); sleep(15000); sendul(m->c, 0); print("exiting mainproc tid=%d pid=%d\n", m->id, threadpid(m->id)); threadexits(nil); } void threadmain(int argc, char *argv[]) { State mainState, *m; State subState, *s; char buf[256]; int i, j, k, l, n, N, maineof, subeof, ret, hang; int p[2]; Alt a[] = { /* c v op */ {nil , nil, CHANRCV}, {nil, nil, CHANRCV}, {nil, nil, CHANEND}, }; hang = 0; //change to 1 to hang N = 1; m = &mainState; s = &subState; print("threadmain tid=%d pid=%d\n", threadid(), threadpid(threadid())); memset(m, 0, sizeof(State)); m->c = chancreate(sizeof(int), 0); a[0].c = m->c; s->c = chancreate(sizeof(int), 0); a[1].c = s->c; for (l=0; l < N; l++) { print("for %d\n", l); if (pipe(p) < 0) { fprint(2, "pipe failed: %r\n"); threadexitsall("pipe failed"); } m->fd = p[0]; m->tobeclosed = p[1]; s->fd = p[1]; s->tobeclosed = p[0]; // m->id = procrfork(mainproc, m, STACK, RFFDG); m->id = proccreate(mainproc, m, STACK); print("started mainproc tid=%d pid=%d\n", m->id, threadpid(m->id)); // s->id = procrfork(subproc, s, STACK, RFFDG); s->id = proccreate(subproc, s, STACK); print("started subproc tid=%d pid=%d\n", m->id, threadpid(m->id)); sleep(60000); print("manthread after sleep\n"); i = 0; j = 1; print("threadmain closing %d\n", p[j]); close(p[j]); print("threadmain closed %d\n", p[j]); if (!hang) { print("threadmain writing zero to %d\n", p[i]); n = write(p[i], buf, 0); print("threadmain write %d returns %d\n", p[i], n); sleep(15000); } print("threadmain closing %d\n", p[i]); close(p[i]); print("threadmain closed %d\n", p[i]); sleep(15000); maineof = 0; subeof = 0; while(!maineof || !subeof) { print("threadmain while alt maineof=%d subeof=%d\n", maineof, subeof); switch(ret = alt(a)){ case 0: print("main eof\n"); maineof = 1; break; case 1: print("sub eof\n"); subeof = 1; break; default: print("should not happen ret=%d\n", ret); sysfatal("should not happen"); } } print("threadmain while alt done\n"); // print("threadmain threadint mainid\n"); // threadint(m->mainid); // print("threadmain done threadint mainid\n"); } print("threadmain exiting\n"); threadexits(nil); } ------- =_aaaaaaaaaa0--