diff options
Diffstat (limited to 'rt')
-rw-r--r-- | rt/aio_misc.c | 2 | ||||
-rw-r--r-- | rt/aio_misc.h | 15 | ||||
-rw-r--r-- | rt/aio_notify.c | 11 | ||||
-rw-r--r-- | rt/aio_suspend.c | 3 | ||||
-rw-r--r-- | rt/lio_listio.c | 17 | ||||
-rw-r--r-- | rt/lio_listio64.c | 17 |
6 files changed, 52 insertions, 13 deletions
diff --git a/rt/aio_misc.c b/rt/aio_misc.c index fb5fbf6..fa3c75c 100644 --- a/rt/aio_misc.c +++ b/rt/aio_misc.c @@ -265,6 +265,8 @@ __aio_enqueue_request (aiocb_union *aiocbp, int operation) return NULL; } newp->aiocbp = aiocbp; + newp->caller_pid = (aiocbp->aiocb.aio_sigevent.sigev_notify == SIGEV_SIGNAL + ? getpid () : 0); newp->waiting = NULL; aiocbp->aiocb.__abs_prio = prio; diff --git a/rt/aio_misc.h b/rt/aio_misc.h index af8e247..e3c93be 100644 --- a/rt/aio_misc.h +++ b/rt/aio_misc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1997 Free Software Foundation, Inc. +/* Copyright (C) 1997, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -50,6 +50,9 @@ struct waitlist volatile int *counterp; /* The next field is used in asynchronous `lio_listio' operations. */ struct sigevent *sigevp; + /* XXX See requestlist, it's used to work around the broken signal + handling in Linux. */ + pid_t caller_pid; }; @@ -76,6 +79,10 @@ struct requestlist /* Pointer to the actual data. */ aiocb_union *aiocbp; + /* PID of the initiator thread. + XXX This is only necessary for the broken signal handling on Linux. */ + pid_t caller_pid; + /* List of waiting processes. */ struct waitlist *waiting; }; @@ -104,9 +111,11 @@ extern void __aio_free_request (struct requestlist *req) internal_function; extern void __aio_notify (struct requestlist *req) internal_function; /* Notify initiator of request. */ -extern int __aio_notify_only (struct sigevent *sigev) internal_function; +extern int __aio_notify_only (struct sigevent *sigev, pid_t caller_pid) + internal_function; /* Send the signal. */ -extern int __aio_sigqueue (int sig, const union sigval val) internal_function; +extern int __aio_sigqueue (int sig, const union sigval val, pid_t caller_pid) + internal_function; #endif /* aio_misc.h */ diff --git a/rt/aio_notify.c b/rt/aio_notify.c index 8c57d72..54e9959 100644 --- a/rt/aio_notify.c +++ b/rt/aio_notify.c @@ -1,5 +1,5 @@ /* Notify initiator of AIO request. - Copyright (C) 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -25,7 +25,7 @@ int internal_function -__aio_notify_only (struct sigevent *sigev) +__aio_notify_only (struct sigevent *sigev, pid_t caller_pid) { int result = 0; @@ -51,7 +51,8 @@ __aio_notify_only (struct sigevent *sigev) } else if (sigev->sigev_notify == SIGEV_SIGNAL) /* We have to send a signal. */ - if (__aio_sigqueue (sigev->sigev_signo, sigev->sigev_value) < 0) + if (__aio_sigqueue (sigev->sigev_signo, sigev->sigev_value, caller_pid) + < 0) result = -1; return result; @@ -65,7 +66,7 @@ __aio_notify (struct requestlist *req) struct waitlist *waitlist; struct aiocb *aiocbp = &req->aiocbp->aiocb; - if (__aio_notify_only (&aiocbp->aio_sigevent) != 0) + if (__aio_notify_only (&aiocbp->aio_sigevent, req->caller_pid) != 0) { /* XXX What shall we do if already an error is set by read/write/fsync? */ @@ -89,7 +90,7 @@ __aio_notify (struct requestlist *req) this request is the last one, send the signal. */ if (*waitlist->counterp == 0) { - __aio_notify_only (waitlist->sigevp); + __aio_notify_only (waitlist->sigevp, waitlist->caller_pid); /* This is tricky. See lio_listio.c for the reason why this works. */ free ((void *) waitlist->counterp); diff --git a/rt/aio_suspend.c b/rt/aio_suspend.c index 70c5e1a..6736857 100644 --- a/rt/aio_suspend.c +++ b/rt/aio_suspend.c @@ -1,5 +1,5 @@ /* Suspend until termination of a requests. - Copyright (C) 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -64,6 +64,7 @@ aio_suspend (list, nent, timeout) waitlist[cnt].next = requestlist[cnt]->waiting; waitlist[cnt].counterp = &dummy; waitlist[cnt].sigevp = NULL; + waitlist[cnt].caller_pid = 0; /* Not needed. */ requestlist[cnt]->waiting = &waitlist[cnt]; none = 0; } diff --git a/rt/lio_listio.c b/rt/lio_listio.c index 03c3bf2..13d1b79 100644 --- a/rt/lio_listio.c +++ b/rt/lio_listio.c @@ -1,5 +1,5 @@ /* Enqueue and list of read or write requests. - Copyright (C) 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -21,6 +21,7 @@ #include <aio.h> #include <errno.h> #include <stdlib.h> +#include <unistd.h> #include "aio_misc.h" @@ -77,8 +78,17 @@ lio_listio (mode, list, nent, sig) { /* We don't have anything to do except signalling if we work asynchronously. */ + + /* Release the mutex. We do this before raising a signal since the + signal handler might do a `siglongjmp' and then the mutex is + locked forever. */ + pthread_mutex_unlock (&__aio_requests_mutex); + if (mode == LIO_NOWAIT) - __aio_notify_only (sig); + __aio_notify_only (sig, + sig->sigev_notify == SIGEV_SIGNAL ? getpid () : 0); + + return result; } else if (mode == LIO_WAIT) { @@ -95,6 +105,7 @@ lio_listio (mode, list, nent, sig) waitlist[cnt].next = requests[cnt]->waiting; waitlist[cnt].counterp = &total; waitlist[cnt].sigevp = NULL; + waitlist[cnt].caller_pid = 0; /* Not needed. */ requests[cnt]->waiting = &waitlist[cnt]; ++total; } @@ -130,6 +141,7 @@ lio_listio (mode, list, nent, sig) } else { + pid_t caller_pid = sig->sigev_notify == SIGEV_SIGNAL ? getpid () : 0; total = 0; for (cnt = 0; cnt < nent; ++cnt) @@ -140,6 +152,7 @@ lio_listio (mode, list, nent, sig) waitlist->list[cnt].next = requests[cnt]->waiting; waitlist->list[cnt].counterp = &waitlist->counter; waitlist->list[cnt].sigevp = &waitlist->sigev; + waitlist->list[cnt].caller_pid = caller_pid; requests[cnt]->waiting = &waitlist->list[cnt]; ++total; } diff --git a/rt/lio_listio64.c b/rt/lio_listio64.c index 9cb1125..5df2596 100644 --- a/rt/lio_listio64.c +++ b/rt/lio_listio64.c @@ -1,5 +1,5 @@ /* Enqueue and list of read or write requests, 64bit offset version. - Copyright (C) 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -21,6 +21,7 @@ #include <aio.h> #include <errno.h> #include <stdlib.h> +#include <unistd.h> #include "aio_misc.h" @@ -77,8 +78,17 @@ lio_listio64 (mode, list, nent, sig) { /* We don't have anything to do except signalling if we work asynchronously. */ + + /* Release the mutex. We do this before raising a signal since the + signal handler might do a `siglongjmp' and then the mutex is + locked forever. */ + pthread_mutex_unlock (&__aio_requests_mutex); + if (mode == LIO_NOWAIT) - __aio_notify_only (sig); + __aio_notify_only (sig, + sig->sigev_notify == SIGEV_SIGNAL ? getpid () : 0); + + return result; } else if (mode == LIO_WAIT) { @@ -95,6 +105,7 @@ lio_listio64 (mode, list, nent, sig) waitlist[cnt].next = requests[cnt]->waiting; waitlist[cnt].counterp = &total; waitlist[cnt].sigevp = NULL; + waitlist[cnt].caller_pid = 0; /* Not needed. */ requests[cnt]->waiting = &waitlist[cnt]; ++total; } @@ -130,6 +141,7 @@ lio_listio64 (mode, list, nent, sig) } else { + pid_t caller_pid = sig->sigev_notify == SIGEV_SIGNAL ? getpid () : 0; total = 0; for (cnt = 0; cnt < nent; ++cnt) @@ -140,6 +152,7 @@ lio_listio64 (mode, list, nent, sig) waitlist->list[cnt].next = requests[cnt]->waiting; waitlist->list[cnt].counterp = &waitlist->counter; waitlist->list[cnt].sigevp = &waitlist->sigev; + waitlist->list[cnt].caller_pid = caller_pid; requests[cnt]->waiting = &waitlist->list[cnt]; ++total; } |