1  #include <aio.h>
       2  #include <errno.h>
       3  #include <signal.h>
       4  #include <stdio.h>
       5  #include <stdlib.h>
       6  #include <pthread.h>
       7  #include <unistd.h>
       8  
       9  static pthread_barrier_t b;
      10  static pthread_t main_thread;
      11  static int flag;
      12  
      13  
      14  static void *
      15  tf (void *arg)
      16  {
      17    int e = pthread_barrier_wait (&b);
      18    if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
      19      {
      20        puts ("child: barrier_wait failed");
      21        exit (1);
      22      }
      23  
      24    /* There is unfortunately no other way to try to make sure the other
      25       thread reached the aio_suspend call.  This test could fail on
      26       highly loaded machines.  */
      27    sleep (2);
      28  
      29    pthread_kill (main_thread, SIGUSR1);
      30  
      31    while (1)
      32      sleep (1000);
      33  
      34    return NULL;
      35  }
      36  
      37  
      38  static void
      39  sh (int sig)
      40  {
      41    flag = 1;
      42  }
      43  
      44  
      45  static int
      46  do_test (void)
      47  {
      48    main_thread = pthread_self ();
      49  
      50    struct sigaction sa;
      51  
      52    sa.sa_handler = sh;
      53    sa.sa_flags = 0;
      54    sigemptyset (&sa.sa_mask);
      55  
      56    if (sigaction (SIGUSR1, &sa, NULL) != 0)
      57      {
      58        puts ("sigaction failed");
      59        return 1;
      60      }
      61  
      62    if (pthread_barrier_init (&b, NULL, 2) != 0)
      63      {
      64        puts ("barrier_init");
      65        return 1;
      66      }
      67  
      68    int fds[2];
      69    if (pipe (fds) != 0)
      70      {
      71        puts ("pipe failed");
      72        return 1;
      73      }
      74  
      75    char buf[42];
      76    struct aiocb req;
      77    req.aio_fildes = fds[0];
      78    req.aio_reqprio = 0;
      79    req.aio_offset = 0;
      80    req.aio_buf = buf;
      81    req.aio_nbytes = sizeof (buf);
      82    req.aio_sigevent.sigev_notify = SIGEV_NONE;
      83  
      84    if (aio_read (&req) != 0)
      85      {
      86        puts ("aio_read failed");
      87        return 1;
      88      }
      89  
      90    pthread_t th;
      91    if (pthread_create (&th, NULL, tf, NULL) != 0)
      92      {
      93        puts ("create failed");
      94        return 1;
      95      }
      96  
      97    int e = pthread_barrier_wait (&b);
      98    if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
      99      {
     100        puts ("parent: barrier_wait failed");
     101        exit (1);
     102      }
     103  
     104    const struct aiocb *list[1];
     105    list[0] = &req;
     106  
     107    e = aio_suspend (list, 1, NULL);
     108    if (e != -1)
     109      {
     110        puts ("aio_suspend succeeded");
     111        return 1;
     112      }
     113    if (errno != EINTR)
     114      {
     115        puts ("aio_suspend did not return EINTR");
     116        return 1;
     117      }
     118  
     119    return 0;
     120  }
     121  
     122  #define TEST_FUNCTION do_test ()
     123  #include "../test-skeleton.c"