From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: Date: Wed, 21 Sep 2005 18:44:53 -0400 From: Russ Cox To: Axel Belinfante Subject: Re: [9fans] thread confusion In-Reply-To: <200509212234.j8LMYrG01220@zamenhof.cs.utwente.nl> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline References: <2e4165d0a4172357099de271ac66cd5e@lsub.org> <200509211505.j8LF5FQ00275@zamenhof.cs.utwente.nl> <200509212025.j8LKPdr29497@demeter.cs.utwente.nl> <200509212234.j8LMYrG01220@zamenhof.cs.utwente.nl> Cc: Fans of the OS Plan 9 from Bell Labs <9fans@cse.psu.edu> Topicbox-Message-UUID: 8e8f770a-ead0-11e9-9d60-3106f5b1d025 It appears that your program, at its core, it is doing this: void readproc(void *v) { int fd; char buf[100]; fd =3D (int)v; read(fd, buf, sizeof buf); } void threadmain(int argc, char **argv) { int p[2]; pipe(p); proccreate(readproc, (void*)p[0], 8192); proccreate(readproc, (void*)p[1], 8192); close(p[0]); /* and here you expect the first readproc to be done */ close(p[1]); /* and here the second */ } Each read call is holding up a reference to its channel inside the kernel, so that even though you've closed the fd and removed the ref from the fd table, there is still a reference to each side of the pipe in the form of the process blocked on the read. I've never been sure whether the implicit ref held during the system call is good behavior, but it's hard to change. In your case, writing 0 (or anything) makes the read finish, releasing the last ref to the underlying pipe when the system call finishes, and then everything cleans up as expected. So you've found your workaround, and now we understand why it works. Russ