125 lines
2.1 KiB
C
125 lines
2.1 KiB
C
#include <aio.h>
|
|
#include <errno.h>
|
|
#include <signal.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <pthread.h>
|
|
#include <unistd.h>
|
|
|
|
static pthread_barrier_t b;
|
|
static pthread_t main_thread;
|
|
static int flag;
|
|
|
|
|
|
static void *
|
|
tf (void *arg)
|
|
{
|
|
int e = pthread_barrier_wait (&b);
|
|
if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
|
|
{
|
|
puts ("child: barrier_wait failed");
|
|
exit (1);
|
|
}
|
|
|
|
/* There is unfortunately no other way to try to make sure the other
|
|
thread reached the aio_suspend call. This test could fail on
|
|
highly loaded machines. */
|
|
sleep (2);
|
|
|
|
pthread_kill (main_thread, SIGUSR1);
|
|
|
|
while (1)
|
|
sleep (1000);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
static void
|
|
sh (int sig)
|
|
{
|
|
flag = 1;
|
|
}
|
|
|
|
|
|
static int
|
|
do_test (void)
|
|
{
|
|
main_thread = pthread_self ();
|
|
|
|
struct sigaction sa;
|
|
|
|
sa.sa_handler = sh;
|
|
sa.sa_flags = 0;
|
|
sigemptyset (&sa.sa_mask);
|
|
|
|
if (sigaction (SIGUSR1, &sa, NULL) != 0)
|
|
{
|
|
puts ("sigaction failed");
|
|
return 1;
|
|
}
|
|
|
|
if (pthread_barrier_init (&b, NULL, 2) != 0)
|
|
{
|
|
puts ("barrier_init");
|
|
return 1;
|
|
}
|
|
|
|
int fds[2];
|
|
if (pipe (fds) != 0)
|
|
{
|
|
puts ("pipe failed");
|
|
return 1;
|
|
}
|
|
|
|
char buf[42];
|
|
struct aiocb req;
|
|
req.aio_fildes = fds[0];
|
|
req.aio_reqprio = 0;
|
|
req.aio_offset = 0;
|
|
req.aio_buf = buf;
|
|
req.aio_nbytes = sizeof (buf);
|
|
req.aio_sigevent.sigev_notify = SIGEV_NONE;
|
|
|
|
if (aio_read (&req) != 0)
|
|
{
|
|
puts ("aio_read failed");
|
|
return 1;
|
|
}
|
|
|
|
pthread_t th;
|
|
if (pthread_create (&th, NULL, tf, NULL) != 0)
|
|
{
|
|
puts ("create failed");
|
|
return 1;
|
|
}
|
|
|
|
int e = pthread_barrier_wait (&b);
|
|
if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
|
|
{
|
|
puts ("parent: barrier_wait failed");
|
|
exit (1);
|
|
}
|
|
|
|
const struct aiocb *list[1];
|
|
list[0] = &req;
|
|
|
|
e = aio_suspend (list, 1, NULL);
|
|
if (e != -1)
|
|
{
|
|
puts ("aio_suspend succeeded");
|
|
return 1;
|
|
}
|
|
if (errno != EINTR)
|
|
{
|
|
puts ("aio_suspend did not return EINTR");
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#define TEST_FUNCTION do_test ()
|
|
#define TIMEOUT 5
|
|
#include "../test-skeleton.c"
|