diff options
author | Ulrich Drepper <drepper@redhat.com> | 2009-10-29 21:01:24 -0700 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2009-10-29 21:01:24 -0700 |
commit | 584715c3a9b0030729e0a8504c820b3bd8d9353d (patch) | |
tree | 9097c35972e90dbcc544567c5b3c705cb0d85e74 /sysdeps | |
parent | c240c3a58f21d72982e74a485bd7c4900f188876 (diff) | |
download | glibc-584715c3a9b0030729e0a8504c820b3bd8d9353d.tar.gz |
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.
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/pthread/aio_misc.c | 26 |
1 files changed, 19 insertions, 7 deletions
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 <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; } |