mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-29 11:41:21 +03:00
Update.
* sysdeps/unix/clock_nanosleep.c (clock_nanosleep): nanosleep takes care of enabling cancellation. * sysdeps/pthread/aio_suspend.c (aio_suspend): Make aio_suspend cancelable. It's not correct to disable cancellation. Instead of a cleanup handler.
This commit is contained in:
@ -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
|
||||
|
Reference in New Issue
Block a user