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]

1.7.8-1: Signals do NOT interrupt interruptible calls in threads.


Hello list.

I have a code that depends on calls that are normally interruptible
by signals to be interrupted by signal delivery also in threads.

In my installation of cygwin I see that calls are interrupted
as long as I do not try to run them inside a thread.

Attached program demonstrates the issue.

Build with:

gcc signal-in-thread.c -lrt

Run with:

./a.exe || echo "Fail."

Best regards.

-- 
  Huginn
GCS d? s: a C++$() UBLS++++$ P++ L++++$ E---
W+(-) N++ w-- O M- V- PS+ PE++ Y PGP-
t--- 5-- X- R !tv b++ DI+++ D+ G e* h r++ y**
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/time.h>
#include <time.h>
#include <errno.h>

void handler( int omit )
	{
	}

int my_sleep( int long ms )
	{
	int err = 0;
	struct timeval tv;
	tv.tv_sec = ms / 1000;
	tv.tv_usec = ( ms % 1000 ) * 1000;
	err = select( 0, NULL, NULL, NULL, &tv );
	return ( ( err == -1 ) && ( errno == EINTR ) ? -1 : 0 );
	}

void* thr( void* err )
	{
	timer_t timerid;
	struct sigevent sev;
	struct itimerspec its;
	sigset_t mask;
	int* perr = ( int* )err;

	*perr = 0;
	do
		{
		if ( sigemptyset( &mask ) != 0 )
			{
			*perr = -1;
			break;
			}
		if ( sigaddset( &mask, SIGALRM ) != 0 )
			{
			*perr = -1;
			break;
			}
		if ( pthread_sigmask( SIG_UNBLOCK, &mask, NULL ) != 0 )
			{
			*perr = -1;
			break;
			}
		sev.sigev_notify = SIGEV_SIGNAL;
		sev.sigev_signo = SIGALRM;
		sev.sigev_value.sival_ptr = &timerid;
		if ( timer_create(CLOCK_REALTIME, &sev, &timerid) != 0 )
			{
			*perr = -1;
			break;
			}
		memset( &its, 0, sizeof ( its ) );
		its.it_value.tv_nsec = 500 * 1000 * 1000;

		if ( timer_settime(timerid, 0, &its, NULL) != 0 )
			{
			*perr = -1;
			break;
			}
		*perr = ( my_sleep( 2000 ) == -1 ? 0 : 1 );
		}
	while ( 0 );

	return ( NULL );
	}

int main( int argc, char *argv[] )
	{
	sigset_t mask;
	struct sigaction sa;
	pthread_t t;
	int err = 0;

	sa.sa_flags = 0;
	sa.sa_handler = &handler;
	do
		{
		if ( sigemptyset( &mask ) != 0 )
			{
			err = -1;
			break;
			}
		if ( sigaddset( &mask, SIGALRM ) != 0 )
			{
			err = -1;
			break;
			}
		if ( sigprocmask( SIG_BLOCK, &mask, NULL ) != 0 )
			{
			err = -1;
			break;
			}
		if ( pthread_sigmask( SIG_BLOCK, &mask, NULL ) != 0 )
			{
			err = -1;
			break;
			}
		if ( sigemptyset( &sa.sa_mask ) != 0 )
			{
			err = -1;
			break;
			}
		if ( sigaddset( &sa.sa_mask, SIGALRM ) != 0 )
			{
			err = -1;
			break;
			}
		if ( sigaction( SIGALRM, &sa, NULL ) != 0 )
			{
			err = -1;
			break;
			}
		if ( pthread_create( &t, NULL, &thr, &err ) != 0 )
			{
			err = -1;
			break;
			}
		if ( pthread_join( t, NULL ) != 0 )
			{
			err = -1;
			break;
			}
		}
	while ( 0 );
	return ( err );
	}

Attachment: cygcheck.out
Description: Text document

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

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