diff options
Diffstat (limited to 'regress')
-rw-r--r-- | regress/lib/libpthread/semaphore/Makefile | 4 | ||||
-rw-r--r-- | regress/lib/libpthread/semaphore/sem_timedwait/Makefile | 5 | ||||
-rw-r--r-- | regress/lib/libpthread/semaphore/sem_timedwait/sem_timedwait.c | 117 |
3 files changed, 124 insertions, 2 deletions
diff --git a/regress/lib/libpthread/semaphore/Makefile b/regress/lib/libpthread/semaphore/Makefile index a9a7dad7b02..6d8b2338af2 100644 --- a/regress/lib/libpthread/semaphore/Makefile +++ b/regress/lib/libpthread/semaphore/Makefile @@ -1,5 +1,5 @@ -# $OpenBSD: Makefile,v 1.1 2012/01/04 17:36:40 mpi Exp $ +# $OpenBSD: Makefile,v 1.2 2012/03/03 11:08:12 guenther Exp $ -SUBDIR = sem_destroy sem_getvalue sem_trywait sem_wait +SUBDIR = sem_destroy sem_getvalue sem_trywait sem_wait sem_timedwait .include <bsd.subdir.mk> diff --git a/regress/lib/libpthread/semaphore/sem_timedwait/Makefile b/regress/lib/libpthread/semaphore/sem_timedwait/Makefile new file mode 100644 index 00000000000..c7168a14afd --- /dev/null +++ b/regress/lib/libpthread/semaphore/sem_timedwait/Makefile @@ -0,0 +1,5 @@ +# $OpenBSD: Makefile,v 1.1 2012/03/03 11:08:12 guenther Exp $ + +PROG= sem_timedwait + +.include <bsd.regress.mk> diff --git a/regress/lib/libpthread/semaphore/sem_timedwait/sem_timedwait.c b/regress/lib/libpthread/semaphore/sem_timedwait/sem_timedwait.c new file mode 100644 index 00000000000..38e0ebe18c7 --- /dev/null +++ b/regress/lib/libpthread/semaphore/sem_timedwait/sem_timedwait.c @@ -0,0 +1,117 @@ +/* $OpenBSD: sem_timedwait.c,v 1.1 2012/03/03 11:08:12 guenther Exp $ */ +/* + * Martin Pieuchot <mpi@openbsd.org>, 2011. Public Domain. + */ + +#include <err.h> +#include <errno.h> +#include <unistd.h> +#include <semaphore.h> +#include <signal.h> +#include <pthread.h> +#include "test.h" + + +void *waiter(void *arg); + +void +handler(int sig) +{ + static char message[] = "got sig\n"; + + write(STDERR_FILENO, message, sizeof(message) - 1); +} + +sem_t sem; +volatile int posted = 0, eintr_ok = 0; + +int +main(int argc, char **argv) +{ + pthread_t th; + struct sigaction sa; + struct timespec ts, ts2; + + CHECKr(clock_gettime(CLOCK_REALTIME, &ts)); + ts.tv_sec += 3; + CHECKn(sem_timedwait(&sem, &ts)); + ASSERT(errno == EINVAL); + + CHECKr(sem_init(&sem, 0, 0)); + + CHECKr(pthread_create(&th, NULL, waiter, &sem)); + + sleep(1); + + printf("expect: sem_destroy on semaphore with waiters!\n"); + CHECKn(sem_destroy(&sem)); + ASSERT(errno == EBUSY); + + posted = 1; + CHECKr(sem_post(&sem)); + CHECKr(pthread_join(th, NULL)); + + /* test that sem_timedwait() resumes after handling a signal */ + memset(&sa, 0, sizeof sa); + sa.sa_handler = &handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction(SIGUSR1, &sa, NULL)) + err(1, "sigaction"); + posted = 0; + CHECKr(pthread_create(&th, NULL, waiter, &sem)); + sleep(1); + fprintf(stderr, "sending sig\n"); + eintr_ok = 1; + pthread_kill(th, SIGUSR1); + sleep(1); + fprintf(stderr, "posting\n"); + posted = 1; + eintr_ok = 0; + CHECKr(sem_post(&sem)); + CHECKr(pthread_join(th, NULL)); + + CHECKr(clock_gettime(CLOCK_REALTIME, &ts)); + ts.tv_sec += 2; + CHECKn(sem_timedwait(&sem, &ts)); + ASSERT(errno == ETIMEDOUT); + CHECKr(clock_gettime(CLOCK_REALTIME, &ts2)); + if (timespeccmp(&ts, &ts2, < )) + timespecsub(&ts2, &ts, &ts); + else + timespecsub(&ts, &ts2, &ts); + CHECKr(clock_getres(CLOCK_REALTIME, &ts2)); + ASSERT(timespeccmp(&ts, &ts2, < )); + + CHECKe(sem_destroy(&sem)); + + SUCCEED; +} + +void * +waiter(void *arg) +{ + sem_t *semp = arg; + struct timespec ts; + int value; + int r; + + CHECKr(clock_gettime(CLOCK_REALTIME, &ts)); + ts.tv_sec += 3; + r = sem_timedwait(semp, &ts); + CHECKr(sem_getvalue(semp, &value)); + if (r == 0) { + ASSERT(value == 0); + ASSERT(posted != 0); + } else { + ASSERT(r == -1); + ASSERT(errno == EINTR); + ASSERT(eintr_ok); + if (posted) + ASSERT(value == 1); + else + ASSERT(value == 0); + } + + return (NULL); +} |