diff options
Diffstat (limited to 'nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c')
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c index 55f3e2e075..90edbc5dd0 100644 --- a/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c +++ b/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c @@ -30,6 +30,21 @@ extern void __sem_wait_cleanup (void *arg) attribute_hidden; +/* This is in a seperate function in order to make sure gcc + puts the call site into an exception region, and thus the + cleanups get properly run. */ +static int +__attribute__ ((noinline)) +do_futex_timed_wait (struct sparc_new_sem *isem, struct timespec *rt) +{ + int err, oldtype = __pthread_enable_asynccancel (); + + err = lll_futex_timed_wait (&isem->value, 0, rt, + isem->private ^ FUTEX_PRIVATE_FLAG); + + __pthread_disable_asynccancel (oldtype); + return err; +} int sem_timedwait (sem_t *sem, const struct timespec *abstime) @@ -99,16 +114,7 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime) /* Do wait. */ rt.tv_sec = sec; rt.tv_nsec = nsec; - - /* Enable asynchronous cancellation. Required by the standard. */ - int oldtype = __pthread_enable_asynccancel (); - - err = lll_futex_timed_wait (&isem->value, 0, &rt, - isem->private ^ FUTEX_PRIVATE_FLAG); - - /* Disable asynchronous cancellation. */ - __pthread_disable_asynccancel (oldtype); - + err = do_futex_timed_wait(isem, &rt); if (err != 0 && err != -EWOULDBLOCK) { __set_errno (-err); |