RE: Problem with pthread_kill, maybe bug?

Christophe Saout <[email protected]> 22 Aug 2002 03:27:42 +0200
Newsgroups gmane.linux.ngpt.user
Message-ID <1029979664.1070.20.camel@chtephan>
Am Mit, 2002-08-21 um 23.35 schrieb [email protected]:

> It may depend on the signal mask of the main thread.  If it is set to ignore
> USR1, then it will not exit...  Linux threads had some pretty bad signal
> handling code.  not posix compliant at all.  NGPT may have fixed that.

No, I think the signal handling code is correct (mysql does not only
work with LinuxThreads but should work with every pthreads
implementation, it does a lot of checks in configure).

I have written a test program that simulates the problem and now believe
that it actually is a NGPT bug.

Look at this:

-------------
#include <stdio.h>
#include <signal.h>
#include <pthread.h>

pthread_t main_thread;

static int killed = 0;

void boum(int signum)
{
   killed = 1;
   printf("Try to kill main thread (%d)\n", signum);
   pthread_kill(main_thread, SIGUSR1);
}

void *subthread(void *arg)
{
   printf("Subthread start\n");
   sleep(5);
   printf("Subthread sleep aborted\n");
   if (!killed)
      boum(-1);
   return NULL;
}
 
int main(int argc, char *argv[])
{
   pthread_t slave_thread;

   signal(SIGINT, boum);
   main_thread = pthread_self();
   if (argc > 1)
      pthread_create(&slave_thread, NULL, subthread, NULL);
   select(0, NULL, NULL, NULL, NULL); /* Wait forever */   
   pthread_join(slave_thread, NULL);
   return 0;
}
----------

You can perform three tests with this small program:

1. Run it without argument (on the console)
It will wait forever (in the select line).
Now you can send it a SIGINT (e.g. by pressing ^C).
The signal handler is run, which in turn sends a SIGUSR1, which isn't
handled and the program should abort with (User defined signal 1) or
something.
This works as expected with both LinuxThreads and NGPT (2.0.1).

2. Run it with an argument (no matter what).
A child thread is created which waits for five seconds and then sends
the main process a SIGUSR1.
You should expect that the program aborts. It does with LinuxThreads
(after five seconds), again with "User defined signal 1", but with NGPT
nothing happens (the signal is lost somewhere).

3. Run it with an argument and send a SIGINT within five seconds
If you send a SIGINT while the child thread is waiting in sleep(5), the
signal handler for SIGINT is called which in turn tries to kill the main
process.
You should expect that the same thing happens as without the command
line argument (without the child thread). With LinuxThreads again, it
works fine (just like the first test). But with NGPT the signal handler
gets called but the SIGUSR1 doesn't arrive in the main thread. Instead
of that you can see that sleep(5) in the client thread is immediately
aborted. But the signal is lost.
If you remove the if (!killed) before boum(-1); you see, that the
pthread_kill from the thread doesn't arrive in the main thread either.