Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 8 Jan 2004 12:13:17 +0100 (CET)
From:      rmkml <rmkml@wanadoo.fr>
To:        freebsd-hackers@freebsd.org
Subject:   problem with signal handling and threads (fbsd49R)
Message-ID:  <Pine.LNX.4.58.0401081150010.12240@hp.mgn.net>

next in thread | raw e-mail | index | archive | help
Hi,

I've got a problem with signal handling and threads.
I've reproduced the problem in a simple code.
Description of program:
 install a signal  handler SIGINT.
 create a thread that do nothing except waiting.
 main thread use poll to wait forever [ poll(,,-1) ].
 user has too crtl-C to interrupt poll
 after 5 ctrl-C, loop is over and main-thread signals sub-thread to
stops.

In fact, it appears not to work correctly: after one ctrl-C, user has to
press ctrl-C twice before poll returns with errno=EINTR !!
If the thread creation is removed from code, the expected behavior is
seen : the program works fine.

If I replace the poll by sigsuspend() the program works fine too.

Is there something wrong with poll function ?

Maybe something is wrong in the approach or in the source code !
Any suggstions are wellcome.

here is sample C code :
_______________________________________
test_thread_signals.c
_______________________________________
#define __EXTENSIONS__
#define _REENTRANT    /* basic first 3-lines for threads */
#define _GNU_SOURCE
#define _THREAD_SAFE
#define _POSIX_PTHREAD_SEMANTICS

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <poll.h>

pthread_mutex_t mutex;
pthread_t thread;
pthread_cond_t condition;

void *run(void *argp);
static void handler(int);

int main(int argc, char **argv)
{
  pthread_attr_t attr;
  register int i, res;
  struct pollfd poll_fd;
  sigset_t set;

  signal(SIGINT, handler);

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

  pthread_mutex_init(&mutex, 0);
  pthread_cond_init(&condition, 0);

 /** comment the following line to see the "normal" behavior **/
  pthread_create(&thread, &attr, run, 0);

  pthread_attr_destroy( &attr );

  poll_fd.fd = -1;
  poll_fd.revents=0;
  poll_fd.events=0;

  sigemptyset(&set);

  puts("main: begin loop");
  for(i=0; i<5; i++)
  {
     /** wait forever **/
     res = poll( &poll_fd, (unsigned long)1, -1 );
    /** using sigsuspend ... **/
/*     res = sigsuspend(&set); */
     if( res == -1 && errno==EINTR )
     {
       puts("ctrl-C received");
     }
     printf("res = %d - errno = %d \n", res, errno );
  }

  puts("send sub thread term signal");
  pthread_cond_signal(&condition);

  puts("main end");
  return 0;
}

void *run(void *argp)
{
  puts("begin sub thread and wait");

  pthread_mutex_lock(&mutex);
  pthread_cond_wait(&condition, &mutex);
  pthread_mutex_unlock(&mutex);

  puts("end sub thread");
  return 0;
}

void handler(int signo)
{
}

_______________________________________
compilation with

$ gcc -g2 -ansi -Wall  -o test_thread_signals.o -c test_thread_signals.c
$ gcc -o test_thread_signals -pthread  test_thread_signals.o

here is the results with the original code :

$ ./test_thread_signals
main: begin loop
begin sub thread and wait
^Cctrl-C received
res = -1 - errno = 4
^C^Cctrl-C received
res = -1 - errno = 4
^C^Cctrl-C received
res = -1 - errno = 4
^C^Cctrl-C received
res = -1 - errno = 4
^C^Cctrl-C received
res = -1 - errno = 4
send sub thread term signal
main end

and the trace with no sub thread :

$ ./test_thread_signals
main: begin loop
^Cctrl-C received
res = -1 - errno = 4
^Cctrl-C received
res = -1 - errno = 4
^Cctrl-C received
res = -1 - errno = 4
^Cctrl-C received
res = -1 - errno = 4
^Cctrl-C received
res = -1 - errno = 4
send sub thread term signal
main end


Regards.

Rmkml@Wanadoo.fr



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.LNX.4.58.0401081150010.12240>