From owner-freebsd-hackers Wed Aug 29 21:56:20 2001 Delivered-To: freebsd-hackers@freebsd.org Received: from merlot.juniper.net (natint.juniper.net [207.17.136.129]) by hub.freebsd.org (Postfix) with ESMTP id E88BF37B401 for ; Wed, 29 Aug 2001 21:56:15 -0700 (PDT) (envelope-from joelh@juniper.net) Received: from sindri.juniper.net (sindri.juniper.net [172.17.22.63]) by merlot.juniper.net (8.11.3/8.11.3) with ESMTP id f7U4uA093317; Wed, 29 Aug 2001 21:56:10 -0700 (PDT) (envelope-from joelh@juniper.net) Received: (from joelh@localhost) by sindri.juniper.net (8.11.1/8.9.3) id f7U4uAR08305; Wed, 29 Aug 2001 21:56:10 -0700 (PDT) (envelope-from joelh@juniper.net) Date: Wed, 29 Aug 2001 21:56:10 -0700 (PDT) Message-Id: <200108300456.f7U4uAR08305@sindri.juniper.net> X-Authentication-Warning: sindri.juniper.net: joelh set sender to joelh@juniper.net using -f To: hackers@freebsd.org Subject: Thoughts on this pthreads bug: why release O_NONBLOCK in _exit? From: Joel Ray Holveck Reply-To: joelh@juniper.net Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG I've been studying a few things in pthreads to figure out a bug that's had me banging my head against a wall. I'd be interested in knowing what peoples' thoughts are. The basic scenario is that a fd loses its schedulability after the process calls daemon(). To review: The current pthreads implementation requires fds to be marked O_NONBLOCK (which pthreads manages itself) to allow scheduling to work properly. The daemon() library call's life (for the purposes of this discussion) is to fork. The parent dies by calling _exit(0), and the child goes on. The _exit routine in libc_r turns off the O_NONBLOCK flag on all file descriptors, except those which the program turned it on for. Now, the problem. The forked parent and child, of course, are sharing fds. So when the forked child exits, the parent's fds have their O_NONBLOCK flags toggled off. If the parent is still running multithreaded, this creates a scheduling problem. I've included a condensed version of the code I've been using to test this below. It's enough to demonstrate the problem, if not the normal symptoms. What I can't figure out is why libc_r's _exit toggles off the O_NONBLOCKs. Any thoughts? Thanks, joelh #include #include #include #include #include #include int main(int argc, char *argv) { pid_t pid; int fd; fd = socket(PF_UNIX, SOCK_DGRAM, 0); printf("flags after open: %x\n", _thread_sys_fcntl(fd, F_GETFL)); fflush(stdout); pid = fork(); if (pid != 0) { printf("flags after fork in parent: %x\n", _thread_sys_fcntl(fd, F_GETFL)); fflush(stdout); /* We use _exit instead of exit to imitate what daemon() * does. */ _exit(0); } else { sleep(1); /* Give the parent time to die */ printf("flags after fork in child: %x\n", _thread_sys_fcntl(fd, F_GETFL)); exit(0); } } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message