This is the mail archive of the libc-help@sourceware.org mailing list for the glibc 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]

Re: tst-cancel4 fails at pselect


In order to track down the problem, I created a test program that calls both
select() and pselect() either directly or by creating a thread. Only if
pselect() is used and called within a thread, it mysteriously returns (most
often).

Can somebody confirm, report different result or explain what is going wrong
here? pselect() should wait forever and be cancelled after the nanosleep!

$ ./test 1
Test #1, with select, direct call
  calling now
^C (cancelled by me)

$ ./test 2
Test #2, with select and thread
  creating thread
  cancelling thread
  end of test

$ ./test 3
Test #3, with pselect, direct call
  calling now
^C (cancelled by me)

$ ./test 4
Test #4, with pselect and thread
  creating thread
Oops! pselect returned with 0     <-- this is mystery

$ ./test 4
Test #4, with pselect and thread  <-- sometimes it works
  creating thread
  cancelling thread
  end of test

The program:

#include <sys/select.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <time.h>

static int fds[2];

static void *test (void *arg)
{
  char *what;
  int ret;

  fd_set rfs;
  FD_ZERO(&rfs);
  FD_SET(fds[0], &rfs);

  if (*(char *) arg == '1' || *(char *) arg == '2')
  {
    what = "select";
    ret = select(fds[0] + 1, &rfs, NULL, NULL, NULL);
  }
  else
  {
    what = "pselect";
    ret = pselect(fds[0] + 1, &rfs, NULL, NULL, NULL, NULL);
  }

  printf("Oops! %s returned with %d\n", what, ret);
  _exit(1);
}

int main (int argc, char **argv)
{
  pthread_t th;
  int thread = (*argv[1] == '2' || *argv[1] == '4');

  printf("Test #%c, ", *argv[1]);

  switch (*argv[1])
  {
    case '1':
      printf("with select, direct call\n");
      break;

    case '2':
      printf("with select and thread\n");
      break;

    case '3':
      printf("with pselect, direct call\n");
      break;

    case '4':
      printf("with pselect and thread\n");
      break;
  }

  if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNIX, fds) != 0)
  {
    perror ("socketpair");
    return 1;
  }

  if (thread)
  {
    puts("  creating thread");

    if (pthread_create (&th, NULL, test, argv[1]) != 0)
    {
      perror("create thread");
      return 1;
    }
  }
  else
  {
    puts("  calling now");
    test(argv[1]);
  }

  struct timespec ts = {.tv_sec = 3, .tv_nsec = 0};

  while (nanosleep(&ts, &ts) != 0) continue;

  if (thread)
  {
    puts("  cancelling thread");

    if (pthread_cancel(th) != 0)
    {
      perror("cancel thread");
      return 1;
    }
  }

  puts ("  end of test");

  return 0;
}


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