Subject: pthread signal handling bug?
From: Karl Vogel <[email-masked]>
To: "[email-masked]'" <[email-masked]>
Date: Wed, 7 Aug 2002 17:12:04 +0200

[NOTE: I'm not subscribed to this list, so please add me in Cc: if you
reply]

I have a problem with signal delivery when using POSIX threads. If you
start 2 threads and sleep in both, but 1 has an alarm() defined, then
when the signal is delivered it also cancels the other thread.

My knowledge of pthreads is limited, so I don't know if this is an
expected result, but I tried the same program on Linux & Digital UNIX V4.0b
and got a different result.

Pseudo code:

	thread 1

		repeat
			print message
			sleep

	thread 2
		set alarm
		sleep
		exit

What I expected was that thread 1 would keep on running and not get any
signals
delivered, while thread 2 would just cancel the sleep and exit. However what
I got was that the sleep from thread 1 fails after the signal got delivered.

Included is the test case source. Following version numbers might be useful:

cygwin              1.3.12-4 
gcc                 3.1.1-4      

On Windows 2000 SP1.

---- test case -----
#include <pthread.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

pthread_mutex_t mux;

void *func(void *x)
{
	int *p = (int *)x;
	time_t t;
	int r;

	/* Print time every 5 seconds */
	while(1) {
		time(&t);
		pthread_mutex_lock(&mux);
		printf("thread %d - %s",*p,ctime(&t)); 
		pthread_mutex_unlock(&mux);
		r= sleep(5);
		if (r) {
			pthread_mutex_lock(&mux);
			printf("Remaining %d\n", r);
			pthread_mutex_unlock(&mux);
		}
	}
	return NULL;
}

void *func2(void *x)
{
	int *p = (int *)x;
	time_t t;

	/* Trigger SIGALRM after 7 seconds */
	time(&t);
	pthread_mutex_lock(&mux);
	printf("thread %d - %s",*p,ctime(&t)); 
	pthread_mutex_unlock(&mux);
	alarm(7);
	sleep(60*60);
	alarm(0);

	time(&t);
	pthread_mutex_lock(&mux);
	printf("exit thread %d - %s",*p,ctime(&t)); 
	pthread_mutex_unlock(&mux);
	return NULL;
}

void sighandler(int sig)
{
	printf("Caught signal\n");
	return;
}

int main()
{
	pthread_t t;
	pthread_t t2;
	pthread_attr_t attr;
	int i;
	int p;
	void *result;

	struct sigaction actions;

	memset((char *)&actions, 0, sizeof(actions));
	sigemptyset(&actions.sa_mask);
	actions.sa_flags = 0;
	actions.sa_handler = sighandler;
	sigaction(SIGALRM, &actions, NULL);

	pthread_mutex_init(&mux, NULL);
	pthread_mutex_lock(&mux);

	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

	i= 1;
	if (pthread_create(&t, &attr, func, &i)!=0) {
		perror("pthread_create t1");
	}
	p= 2;
	if (pthread_create(&t2, &attr, func2, &p)!=0) {
		perror("pthread_create t2");
	}

	printf("Main thread\n");
	pthread_mutex_unlock(&mux);

	pthread_join(t, &result);
	pthread_join(t2, &result);
	pthread_mutex_destroy(&mux);
	return 0;
}
--------------------

Compile with:
	gcc -o tester tester.c -lpthread

Output on cygwin:

$ ./tester
Main thread
thread 1 - Wed Aug  7 17:00:55 2002
thread 2 - Wed Aug  7 17:00:55 2002
thread 1 - Wed Aug  7 17:01:00 2002
exit thread 2 - Wed Aug  7 17:01:02 2002
Remaining 3
thread 1 - Wed Aug  7 17:01:02 2002
Remaining 5
thread 1 - Wed Aug  7 17:01:02 2002
Remaining 5
thread 1 - Wed Aug  7 17:01:02 2002
Remaining 5
thread 1 - Wed Aug  7 17:01:02 2002
Remaining 5
thread 1 - Wed Aug  7 17:01:02 2002

Output on Linux & Digital UNIX:

$ ./tester
Main thread
thread 1 - Wed Aug  7 17:00:02 2002
thread 2 - Wed Aug  7 17:00:02 2002
thread 1 - Wed Aug  7 17:00:07 2002
Caught signal
exit thread 2 - Wed Aug  7 17:00:09 2002
thread 1 - Wed Aug  7 17:00:12 2002
thread 1 - Wed Aug  7 17:00:17 2002
thread 1 - Wed Aug  7 17:00:22 2002

Am I making a gross mistake here?! Or is there a problem with cygwin?

Rgrds,

Karl Vogel
----------
Violence in reality is quite different from theory.
		-- Spock, "The Cloud Minders", stardate 5818.4

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/