| lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame] | 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_lio_opcode = LIO_READ; | 
 | 79 |   req.aio_reqprio = 0; | 
 | 80 |   req.aio_offset = 0; | 
 | 81 |   req.aio_buf = buf; | 
 | 82 |   req.aio_nbytes = sizeof (buf); | 
 | 83 |   req.aio_sigevent.sigev_notify = SIGEV_NONE; | 
 | 84 |  | 
 | 85 |   pthread_t th; | 
 | 86 |   if (pthread_create (&th, NULL, tf, NULL) != 0) | 
 | 87 |     { | 
 | 88 |       puts ("create failed"); | 
 | 89 |       return 1; | 
 | 90 |     } | 
 | 91 |  | 
 | 92 |   int e = pthread_barrier_wait (&b); | 
 | 93 |   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) | 
 | 94 |     { | 
 | 95 |       puts ("parent: barrier_wait failed"); | 
 | 96 |       exit (1); | 
 | 97 |     } | 
 | 98 |  | 
 | 99 |   struct aiocb *list[1]; | 
 | 100 |   list[0] = &req; | 
 | 101 |  | 
 | 102 |   e = lio_listio (LIO_WAIT, list, 1, NULL); | 
 | 103 |   if (e != -1) | 
 | 104 |     { | 
 | 105 |       puts ("lio_listio succeeded"); | 
 | 106 |       return 1; | 
 | 107 |     } | 
 | 108 |   if (errno != EINTR) | 
 | 109 |     { | 
 | 110 |       printf ("lio_listio did not return EINTR: %d (%d = %m)\n", e, errno); | 
 | 111 |       return 1; | 
 | 112 |     } | 
 | 113 |  | 
 | 114 |   return 0; | 
 | 115 | } | 
 | 116 |  | 
 | 117 | #define TEST_FUNCTION do_test () | 
 | 118 | #define TIMEOUT 5 | 
 | 119 | #include "../test-skeleton.c" |