Fix AIO when thread creation failed.

Several bugs fixed when we needed to create a thread to work on AIO
requests but failed and there is not one running.
This commit is contained in:
Ulrich Drepper 2009-10-29 21:01:24 -07:00
parent c240c3a58f
commit 584715c3a9
2 changed files with 24 additions and 7 deletions

View File

@ -1,5 +1,10 @@
2009-10-29 Ulrich Drepper <drepper@redhat.com> 2009-10-29 Ulrich Drepper <drepper@redhat.com>
[BZ #10643]
* sysdeps/pthread/aio_misc.c (__aio_enqueue_request): If thread
creation filed, remove the request from the 'requests' list and signal
the caller that the request is finished.
[BZ #10692] [BZ #10692]
* nis/nss_nis/nis-grp.c (internal_nis_getgrent_r): Don't free buffer * nis/nss_nis/nis-grp.c (internal_nis_getgrent_r): Don't free buffer
in error if batch_read. Patch by Joe Landers <jlanders@vmware.com>. in error if batch_read. Patch by Joe Landers <jlanders@vmware.com>.

View File

@ -1,5 +1,5 @@
/* Handle general operations. /* Handle general operations.
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2006, 2007 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2006, 2007, 2009
Free Software Foundation, Inc. Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@ -372,9 +372,13 @@ __aio_enqueue_request (aiocb_union *aiocbp, int operation)
/* Simply enqueue it after the running one according to the /* Simply enqueue it after the running one according to the
priority. */ priority. */
last = NULL;
while (runp->next_prio != NULL while (runp->next_prio != NULL
&& runp->next_prio->aiocbp->aiocb.__abs_prio >= prio) && runp->next_prio->aiocbp->aiocb.__abs_prio >= prio)
runp = runp->next_prio; {
last = runp;
runp = runp->next_prio;
}
newp->next_prio = runp->next_prio; newp->next_prio = runp->next_prio;
runp->next_prio = newp; runp->next_prio = newp;
@ -403,6 +407,7 @@ __aio_enqueue_request (aiocb_union *aiocbp, int operation)
} }
newp->next_prio = NULL; newp->next_prio = NULL;
last = NULL;
} }
if (running == yes) if (running == yes)
@ -423,7 +428,8 @@ __aio_enqueue_request (aiocb_union *aiocbp, int operation)
running = newp->running = allocated; running = newp->running = allocated;
/* Now try to start a thread. */ /* Now try to start a thread. */
if (aio_create_helper_thread (&thid, handle_fildes_io, newp) == 0) result = aio_create_helper_thread (&thid, handle_fildes_io, newp);
if (result == 0)
/* We managed to enqueue the request. All errors which can /* We managed to enqueue the request. All errors which can
happen now can be recognized by calls to `aio_return' and happen now can be recognized by calls to `aio_return' and
`aio_error'. */ `aio_error'. */
@ -434,10 +440,14 @@ __aio_enqueue_request (aiocb_union *aiocbp, int operation)
running = newp->running = yes; running = newp->running = yes;
if (nthreads == 0) if (nthreads == 0)
/* We cannot create a thread in the moment and there is {
also no thread running. This is a problem. `errno' is /* We cannot create a thread in the moment and there is
set to EAGAIN if this is only a temporary problem. */ also no thread running. This is a problem. `errno' is
result = -1; set to EAGAIN if this is only a temporary problem. */
__aio_remove_request (last, newp, 0);
}
else
result = 0;
} }
} }
} }
@ -459,6 +469,8 @@ __aio_enqueue_request (aiocb_union *aiocbp, int operation)
{ {
/* Something went wrong. */ /* Something went wrong. */
__aio_free_request (newp); __aio_free_request (newp);
aiocbp->aiocb.__error_code = result;
__set_errno (result);
newp = NULL; newp = NULL;
} }