This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

File descriptor lossage during thread termination


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).

<TESTCASE>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <sys/select.h>
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);
}
</TESTCASE>

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/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]