Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
glibc/nptl/tst-cancel24.cc
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
113 lines (89 sloc)
1.74 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <pthread.h> | |
#include <semaphore.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <unistd.h> | |
static volatile bool destr_called; | |
static volatile bool except_caught; | |
static pthread_barrier_t b; | |
struct monitor | |
{ | |
// gcc is broken and would generate a warning without this dummy | |
// constructor. | |
monitor () { } | |
~monitor() { destr_called = true; } | |
}; | |
static void * | |
tf (void *arg) | |
{ | |
sem_t *s = static_cast<sem_t *> (arg); | |
try | |
{ | |
monitor m; | |
pthread_barrier_wait (&b); | |
while (1) | |
sem_wait (s); | |
} | |
catch (...) | |
{ | |
except_caught = true; | |
throw; | |
} | |
return NULL; | |
} | |
static int | |
do_test () | |
{ | |
if (pthread_barrier_init (&b, NULL, 2) != 0) | |
{ | |
puts ("barrier_init failed"); | |
return 1; | |
} | |
sem_t s; | |
if (sem_init (&s, 0, 0) != 0) | |
{ | |
puts ("sem_init failed"); | |
return 1; | |
} | |
pthread_t th; | |
if (pthread_create (&th, NULL, tf, &s) != 0) | |
{ | |
puts ("pthread_create failed"); | |
return 1; | |
} | |
pthread_barrier_wait (&b); | |
/* There is unfortunately no better method to try to assure the | |
child thread reached the sem_wait call and is actually waiting | |
than to sleep here. */ | |
sleep (1); | |
if (pthread_cancel (th) != 0) | |
{ | |
puts ("cancel failed"); | |
return 1; | |
} | |
void *res; | |
if (pthread_join (th, &res) != 0) | |
{ | |
puts ("join failed"); | |
return 1; | |
} | |
if (res != PTHREAD_CANCELED) | |
{ | |
puts ("thread was not canceled"); | |
return 1; | |
} | |
if (! except_caught) | |
{ | |
puts ("exception not caught"); | |
return 1; | |
} | |
if (! destr_called) | |
{ | |
puts ("destructor not called"); | |
return 1; | |
} | |
return 0; | |
} | |
#define TEST_FUNCTION do_test () | |
#define TIMEOUT 3 | |
#include "../test-skeleton.c" |