#include <errno.h> #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> #define NKEYS 100 static pthread_key_t keys[NKEYS]; static pthread_barrier_t b; static void * tf (void *arg) { void *res = NULL; for (int i = 0; i < NKEYS; ++i) { void *p = pthread_getspecific (keys[i]); pthread_setspecific (keys[i], (void *) 7); if (p != NULL) res = p; } if (arg != NULL) { pthread_barrier_wait (arg); pthread_barrier_wait (arg); } return res; } static int do_test (void) { pthread_barrier_init (&b, NULL, 2); for (int i = 0; i < NKEYS; ++i) if (pthread_key_create (&keys[i], NULL) != 0) { puts ("cannot create keys"); return 1; } pthread_t th; if (pthread_create (&th, NULL, tf, &b) != 0) { puts ("cannot create thread in parent"); return 1; } pthread_barrier_wait (&b); pid_t pid = fork (); if (pid == 0) { if (pthread_create (&th, NULL, tf, NULL) != 0) { puts ("cannot create thread in child"); exit (1); } void *res; pthread_join (th, &res); exit (res != NULL); } else if (pid == -1) { puts ("cannot create child process"); return 1; } int s; if (TEMP_FAILURE_RETRY (waitpid (pid, &s, 0)) != pid) { puts ("failing to wait for child process"); return 1; } pthread_barrier_wait (&b); pthread_join (th, NULL); return !WIFEXITED (s) ? 2 : WEXITSTATUS (s); } #define TEST_FUNCTION do_test () #include "../test-skeleton.c"