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. Index: glibc-2.5-20061008T1257/rtkaio/sysdeps/unix/sysv/linux/kaio_misc.c =================================================================== --- glibc-2.5-20061008T1257.orig/rtkaio/sysdeps/unix/sysv/linux/kaio_misc.c +++ glibc-2.5-20061008T1257/rtkaio/sysdeps/unix/sysv/linux/kaio_misc.c @@ -617,7 +617,8 @@ __aio_enqueue_user_request (struct reque 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'. */ @@ -628,10 +629,14 @@ __aio_enqueue_user_request (struct reque 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 (NULL, newp, 0); + } + else + result = 0; } } } @@ -658,7 +663,7 @@ struct requestlist * internal_function __aio_enqueue_request_ctx (aiocb_union *aiocbp, int operation, kctx_t kctx) { - int policy, prio; + int policy, prio, result; struct sched_param param; struct requestlist *newp; int op = (operation & 0xffff); @@ -793,10 +798,13 @@ __aio_enqueue_request_ctx (aiocb_union * newp->kioctx = KCTX_NONE; } - if (__aio_enqueue_user_request (newp)) + result = __aio_enqueue_user_request (newp); + if (result) { /* Something went wrong. */ __aio_free_request (newp); + aiocbp->aiocb.__error_code = result; + __set_errno (result); newp = NULL; } Index: glibc-2.5-20061008T1257/sysdeps/pthread/aio_misc.c =================================================================== --- glibc-2.5-20061008T1257.orig/sysdeps/pthread/aio_misc.c +++ glibc-2.5-20061008T1257/sysdeps/pthread/aio_misc.c @@ -372,9 +372,13 @@ __aio_enqueue_request (aiocb_union *aioc /* 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 *aioc } newp->next_prio = NULL; + last = NULL; } if (running == yes) @@ -423,7 +428,8 @@ __aio_enqueue_request (aiocb_union *aioc 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 *aioc 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 *aioc { /* Something went wrong. */ __aio_free_request (newp); + aiocbp->aiocb.__error_code = result; + __set_errno (result); newp = NULL; }