Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com From: "Ivan Warren" To: Subject: File descriptor lossage during thread termination Date: Wed, 6 Oct 2004 19:14:12 +0200 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Hello, I am encountering the following problem : I have a multithreaded application. Some of the inter-thread communication is performed by pipes (pipe()).. One thread issues a 'select' and the other one writes to it.. However, I am encountering a situation when another thread (not necessaraly involved in the above communication) under the same process, terminates (through return), some (or all) of the pipe (and possibly other) file descriptors become unavailable. This leads to, such symptoms as 'select' giving an errno of 9 (EBADF : Bad File Descriptor). I am currently running 1.5.11 (release). The following test case demonstrates the issue. This is invoked with 0 or n arguments. With n arguments, a new thread is created and then terminates after 4 seconds. When this happens, select receives rc<0 and the program terminates (via exit()). Also, this same testcase does not exhibit that particular behaviour on other posix systems (tried on linux anyways). The application that is being affected by this issue doesn't seem to have any problem running under 1.5.10 (haven't tried this particular test case under 1.5.10 though). #include #include #include #include #include void *thr(void *); void *thr1(void *); int fds[2]; int main(int ac,char **av) { int rc; pthread_t pt; fd_set rfd; av=av; pipe(fds); if (ac>1) pthread_create(&pt,NULL,thr1,NULL); if(pthread_create(&pt,NULL,thr,NULL)) { perror("CT"); exit(1); } while(1) { FD_ZERO(&rfd); FD_SET(fds[0],&rfd); FD_SET(0,&rfd); rc=select(fds[0]+1,&rfd,NULL,NULL,NULL); if(rc<0) { perror("select"); exit(1); } if(FD_ISSET(fds[0],&rfd)) { char c[256]; rc=read(fds[0],c,256); printf("Read %d chars from pipe\n",rc); } if(FD_ISSET(0,&rfd)) { char c[256]; rc=read(0,c,256); printf("Read %d chars from kbd\n",rc); } } } void *thr(void *x) { x=x; while(1) { sleep(1); write(fds[1],"X",1); } return(NULL); } void *thr1(void *x) { x=x; sleep(4); return(NULL); } Thank you, --Ivan -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/