aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2009-10-29 21:01:24 -0700
committerUlrich Drepper <drepper@redhat.com>2009-10-29 21:01:24 -0700
commit584715c3a9b0030729e0a8504c820b3bd8d9353d (patch)
tree9097c35972e90dbcc544567c5b3c705cb0d85e74
parentc240c3a58f21d72982e74a485bd7c4900f188876 (diff)
downloadglibc-584715c3a9b0030729e0a8504c820b3bd8d9353d.zip
glibc-584715c3a9b0030729e0a8504c820b3bd8d9353d.tar.gz
glibc-584715c3a9b0030729e0a8504c820b3bd8d9353d.tar.bz2
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.
-rw-r--r--ChangeLog5
-rw-r--r--sysdeps/pthread/aio_misc.c26
2 files changed, 24 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index d2089f5..8bbc93c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
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]
* 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>.
diff --git a/sysdeps/pthread/aio_misc.c b/sysdeps/pthread/aio_misc.c
index fd3fcbb..c82acbb 100644
--- a/sysdeps/pthread/aio_misc.c
+++ b/sysdeps/pthread/aio_misc.c
@@ -1,5 +1,5 @@
/* 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.
This file is part of the GNU C Library.
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
priority. */
+ last = NULL;
while (runp->next_prio != NULL
&& runp->next_prio->aiocbp->aiocb.__abs_prio >= prio)
- runp = runp->next_prio;
+ {
+ last = runp;
+ runp = runp->next_prio;
+ }
newp->next_prio = runp->next_prio;
runp->next_prio = newp;
@@ -403,6 +407,7 @@ __aio_enqueue_request (aiocb_union *aiocbp, int operation)
}
newp->next_prio = NULL;
+ last = NULL;
}
if (running == yes)
@@ -423,7 +428,8 @@ __aio_enqueue_request (aiocb_union *aiocbp, int operation)
running = newp->running = allocated;
/* 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
happen now can be recognized by calls to `aio_return' and
`aio_error'. */
@@ -434,10 +440,14 @@ __aio_enqueue_request (aiocb_union *aiocbp, int operation)
running = newp->running = yes;
if (nthreads == 0)
- /* We cannot create a thread in the moment and there is
- also no thread running. This is a problem. `errno' is
- set to EAGAIN if this is only a temporary problem. */
- result = -1;
+ {
+ /* We cannot create a thread in the moment and there is
+ also no thread running. This is a problem. `errno' is
+ 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. */
__aio_free_request (newp);
+ aiocbp->aiocb.__error_code = result;
+ __set_errno (result);
newp = NULL;
}