diff options
Diffstat (limited to 'rt/aio_suspend.c')
-rw-r--r-- | rt/aio_suspend.c | 53 |
1 files changed, 30 insertions, 23 deletions
diff --git a/rt/aio_suspend.c b/rt/aio_suspend.c index 6123b7baa0..ca16342a60 100644 --- a/rt/aio_suspend.c +++ b/rt/aio_suspend.c @@ -1,5 +1,5 @@ /* Suspend until termination of a requests. - Copyright (C) 1997 Free Software Foundation, Inc. + Copyright (C) 1997, 1998 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -40,40 +40,42 @@ aio_suspend (list, nent, timeout) int nent; const struct timespec *timeout; { - pthread_cond_t cond; struct waitlist waitlist[nent]; struct requestlist *requestlist[nent]; + pthread_cond_t cond; int cnt; int result = 0; + int dummy; + int none = 1; /* Request the mutex. */ pthread_mutex_lock (&__aio_requests_mutex); - /* First look whether there is already a terminated request. */ + /* There is not yet a finished request. Signal the request that + we are working for it. */ for (cnt = 0; cnt < nent; ++cnt) - if (list[cnt] != NULL && list[cnt]->__error_code != EINPROGRESS) - break; + if (list[cnt] != NULL && list[cnt]->__error_code == EINPROGRESS) + { + requestlist[cnt] = __aio_find_req ((aiocb_union *) list[cnt]); + + if (requestlist[cnt] != NULL) + { + waitlist[cnt].cond = &cond; + waitlist[cnt].next = requestlist[cnt]->waiting; + waitlist[cnt].counterp = &dummy; + waitlist[cnt].sigevp = NULL; + requestlist[cnt]->waiting = &waitlist[cnt]; + none = 0; + } + } - if (cnt == nent) + /* If there is a not finished request wait for it. */ + if (!none) { int oldstate; - /* There is not yet a finished request. Signal the request that - we are working for it. */ - for (cnt = 0; cnt < nent; ++cnt) - if (list[cnt] != NULL && list[cnt]->__error_code == EINPROGRESS) - { - requestlist[cnt] = __aio_find_req ((aiocb_union *) list[cnt]); - - if (requestlist[cnt] != NULL) - { - waitlist[cnt].cond = &cond; - waitlist[cnt].next = requestlist[cnt]->waiting; - waitlist[cnt].counterp = NULL; - waitlist[cnt].sigevp = NULL; - requestlist[cnt]->waiting = &waitlist[cnt]; - } - } + /* Initialize the conditional variable. */ + pthread_cond_init (&cond, NULL); /* Since `pthread_cond_wait'/`pthread_cond_timedwait' are cancelation points we must be careful. We added entries to the waiting lists @@ -87,7 +89,7 @@ aio_suspend (list, nent, timeout) timeout); /* Now remove the entry in the waiting list for all requests - which didn't terminate */ + which didn't terminate. */ for (cnt = 0; cnt < nent; ++cnt) if (list[cnt] != NULL && list[cnt]->__error_code == EINPROGRESS && requestlist[cnt] != NULL) @@ -107,6 +109,11 @@ aio_suspend (list, nent, timeout) /* Now it's time to restore the cancelation state. */ pthread_setcancelstate (oldstate, NULL); + /* Release the conditional variable. */ + if (pthread_cond_destroy (&cond) != 0) + /* This must never happen. */ + abort (); + if (result != 0) { /* An error occurred. Possibly it's EINTR. We have to translate |