delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2004/10/06/13:14:20

Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
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" <ivan AT vmfacility DOT fr>
To: <cygwin AT cygwin DOT com>
Subject: File descriptor lossage during thread termination
Date: Wed, 6 Oct 2004 19:14:12 +0200
Message-ID: <IOEOJNOGAAKFBLIMGDCJMEIMCAAA.ivan@vmfacility.fr>
MIME-Version: 1.0
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).

<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/

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019