From 584715c3a9b0030729e0a8504c820b3bd8d9353d Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 29 Oct 2009 21:01:24 -0700 Subject: [PATCH] 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. --- ChangeLog | 5 +++++ sysdeps/pthread/aio_misc.c | 26 +++++++++++++++++++------- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index d2089f5e2c..8bbc93c6cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2009-10-29 Ulrich Drepper + [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 . diff --git a/sysdeps/pthread/aio_misc.c b/sysdeps/pthread/aio_misc.c index fd3fcbb755..c82acbbc2d 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 , 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; } -- 2.11.4.GIT