diff --git a/ChangeLog b/ChangeLog index 52f18de2d6..6ede713174 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +1999-08-15 Ulrich Drepper + + * sysdeps/unix/sysv/linux/aio_sigqueue.c: Take extra parameter and + initialize si_pid from it. + * sysdeps/generic/aio_sigqueue.c (__aio_sigqueue): Take extra + parameter. + * rt/aio_misc.c (__aio_enqueue_request): Initialize caller_pid. + * rt/aio_misc.h (struct waitlist): Add caller_pid element. + (struct requestlist): Likewise. + Adjust prototypes of __aio_notify_only and __aio_sigqueue. + * rt/notify.c (__aio_notify_only): Take extra parameter. Pass it + to __aio_sigqueue. + (__aio_notify): Pass caller PID to __aio_notify_only. + * rt/aio_suspend.c: Initialize caller_pid. + * rt/lio_listio.c: Likewise. + * rt/lio_listio64.c: Likewise. + + * rt/lio_listio.c: If nothing has to be done free mutex before + signalling. + * rt/lio_listio64.c: Likewise. + 1999-08-10 H.J. Lu * resolv/nss_dns/dns-host.c (getanswer_r): Cleanup out-of- diff --git a/rt/aio_misc.c b/rt/aio_misc.c index fb5fbf6985..fa3c75c150 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 af8e2479ba..e3c93bef36 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 8c57d72e9b..54e9959bfa 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 , 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 70c5e1a3ce..6736857ba1 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 , 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 03c3bf2f6b..13d1b79a58 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 , 1997. @@ -21,6 +21,7 @@ #include #include #include +#include #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 9cb1125f65..5df2596c0f 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 , 1997. @@ -21,6 +21,7 @@ #include #include #include +#include #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; } diff --git a/sysdeps/generic/aio_sigqueue.c b/sysdeps/generic/aio_sigqueue.c index 0a871e24d9..bc703518d4 100644 --- a/sysdeps/generic/aio_sigqueue.c +++ b/sysdeps/generic/aio_sigqueue.c @@ -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 @@ -23,7 +23,7 @@ #include "aio_misc.h" int -__aio_sigqueue (int sig, const union sigval val) +__aio_sigqueue (int sig, const union sigval val, pid_t caller_pid) { __set_errno (ENOSYS); return -1; diff --git a/sysdeps/unix/sysv/linux/aio_sigqueue.c b/sysdeps/unix/sysv/linux/aio_sigqueue.c index 0500b3fbfa..94a8ce0d2a 100644 --- a/sysdeps/unix/sysv/linux/aio_sigqueue.c +++ b/sysdeps/unix/sysv/linux/aio_sigqueue.c @@ -1,4 +1,4 @@ -/* 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. The GNU C Library is free software; you can redistribute it and/or @@ -32,9 +32,10 @@ extern int __syscall_rt_sigqueueinfo (int, int, siginfo_t *); /* Return any pending signal or wait for one for the given time. */ int -__aio_sigqueue (sig, val) +__aio_sigqueue (sig, val, caller_pid) int sig; const union sigval val; + pid_t caller_pid; { siginfo_t info; @@ -42,7 +43,7 @@ __aio_sigqueue (sig, val) info.si_signo = sig; info.si_errno = 0; info.si_code = SI_ASYNCIO; - info.si_pid = getpid (); + info.si_pid = caller_pid; info.si_uid = getuid (); info.si_value = val;