diff options
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/pthread/aio_suspend.c | 62 | ||||
-rw-r--r-- | sysdeps/unix/clock_nanosleep.c | 12 |
2 files changed, 56 insertions, 18 deletions
diff --git a/sysdeps/pthread/aio_suspend.c b/sysdeps/pthread/aio_suspend.c index ffc1c64703..1b09aef028 100644 --- a/sysdeps/pthread/aio_suspend.c +++ b/sysdeps/pthread/aio_suspend.c @@ -35,9 +35,54 @@ #include <stdlib.h> #include <sys/time.h> +#include <bits/libc-lock.h> #include "aio_misc.h" +struct clparam +{ + const struct aiocb *const *list; + struct waitlist *waitlist; + struct requestlist **requestlist; + pthread_cond_t *cond; + int nent; +}; + + +static void +cleanup (void *arg) +{ + const struct clparam *param = (const struct clparam *) arg; + + /* Now remove the entry in the waiting list for all requests + which didn't terminate. */ + int cnt = param->nent; + while (cnt-- > 0) + if (param->list[cnt] != NULL + && param->list[cnt]->__error_code == EINPROGRESS) + { + struct waitlist **listp; + + assert (param->requestlist[cnt] != NULL); + + /* There is the chance that we cannot find our entry anymore. This + could happen if the request terminated and restarted again. */ + listp = ¶m->requestlist[cnt]->waiting; + while (*listp != NULL && *listp != ¶m->waitlist[cnt]) + listp = &(*listp)->next; + + if (*listp != NULL) + *listp = (*listp)->next; + } + + /* Release the conditional variable. */ + (void) pthread_cond_destroy (param->cond); + + /* Release the mutex. */ + pthread_mutex_unlock (&__aio_requests_mutex); +} + + int aio_suspend (list, nent, timeout) const struct aiocb *const list[]; @@ -87,12 +132,16 @@ aio_suspend (list, nent, timeout) /* Only if none of the entries is NULL or finished to be wait. */ if (cnt == nent && any) { - int oldstate; + struct clparam clparam = + { + .list = list, + .waitlist = waitlist, + .requestlist = requestlist, + .cond = &cond, + .nent = nent + }; - /* Since `pthread_cond_wait'/`pthread_cond_timedwait' are cancelation - points we must be careful. We added entries to the waiting lists - which we must remove. So defer cancelation for now. */ - pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &oldstate); + __libc_cleanup_region_start (1, cleanup, &clparam); if (timeout == NULL) result = pthread_cond_wait (&cond, &__aio_requests_mutex); @@ -116,8 +165,7 @@ aio_suspend (list, nent, timeout) &abstime); } - /* Now it's time to restore the cancellation state. */ - pthread_setcancelstate (oldstate, NULL); + __libc_cleanup_region_end (0); } /* Now remove the entry in the waiting list for all requests diff --git a/sysdeps/unix/clock_nanosleep.c b/sysdeps/unix/clock_nanosleep.c index 34bbc2dae6..7662d1704e 100644 --- a/sysdeps/unix/clock_nanosleep.c +++ b/sysdeps/unix/clock_nanosleep.c @@ -94,15 +94,5 @@ clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, /* Not supported. */ return ENOTSUP; - if (SINGLE_THREAD_P) - return __builtin_expect (nanosleep (req, rem), 0) ? errno : 0; - - /* More than one thread running, enable cancellation. */ - int oldstate = LIBC_CANCEL_ASYNC (); - - int result = __builtin_expect (nanosleep (req, rem), 0) ? errno : 0; - - LIBC_CANCEL_RESET (oldstate); - - return result; + return __builtin_expect (nanosleep (req, rem), 0) ? errno : 0; } |