diff options
38 files changed, 730 insertions, 149 deletions
@@ -1,3 +1,44 @@ +2002-12-15 Ulrich Drepper <drepper@redhat.com> + + * sysdeps/generic/sysdep-cancel.h: Add dummy definitions for + SINGLE_THREAD_P, LIBC_CANCEL_ASYNC, and LIBC_CANCEL_RESET. + + * sysdeps/unix/sysv/linux/open64.c: New file. + + * sysdeps/generic/pselect.c: Add support for cancellation handling. + * sysdeps/posix/open64.c: Likewise. + * sysdeps/posix/sigpause.c: Likewise. + * sysdeps/posix/sigwait.c: Likewise. + * sysdeps/posix/system.c: Likewise. + * sysdeps/posix/waitid.c: Likewise. + * sysdeps/unix/sysv/linux/accept.S: Likewise. + * sysdeps/unix/sysv/linux/connect.S: Likewise. + * sysdeps/unix/sysv/linux/llseek.c: Likewise. + * sysdeps/unix/sysv/linux/msgrcv.c: Likewise. + * sysdeps/unix/sysv/linux/msgsnd.c: Likewise. + * sysdeps/unix/sysv/linux/poll.c: Likewise. + * sysdeps/unix/sysv/linux/pread.c: Likewise. + * sysdeps/unix/sysv/linux/pread64.c: Likewise. + * sysdeps/unix/sysv/linux/pwrite.c: Likewise. + * sysdeps/unix/sysv/linux/pwrite64.c: Likewise. + * sysdeps/unix/sysv/linux/readv.c: Likewise. + * sysdeps/unix/sysv/linux/recv.S: Likewise. + * sysdeps/unix/sysv/linux/recvfrom.S: Likewise. + * sysdeps/unix/sysv/linux/recvmsg.S: Likewise. + * sysdeps/unix/sysv/linux/send.S: Likewise. + * sysdeps/unix/sysv/linux/sendmsg.S: Likewise. + * sysdeps/unix/sysv/linux/sendto.S: Likewise. + * sysdeps/unix/sysv/linux/sigsuspend.c: Likewise. + * sysdeps/unix/sysv/linux/sigtimedwait.c: Likewise. + * sysdeps/unix/sysv/linux/sigwait.c: Likewise. + * sysdeps/unix/sysv/linux/sigwaitinfo.c: Likewise. + * sysdeps/unix/sysv/linux/tcdrain.c: Likewise. + * sysdeps/unix/sysv/linux/wait.c: Likewise. + * sysdeps/unix/sysv/linux/waitpid.c: Likewise. + * sysdeps/unix/sysv/linux/writev.c: Likewise. + * sysdeps/unix/sysv/linux/i386/fcntl.c: Likewise. + * sysdeps/unix/sysv/linux/i386/socket.S: Likewise. + 2002-12-14 Jakub Jelinek <jakub@redhat.com> * sysdeps/generic/sysdep-cancel.h: New file. diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 24abd2b541..2296c17803 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,9 @@ +2002-12-15 Ulrich Drepper <drepper@redhat.com> + + * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h: Define + SINGLE_THREAD_P. If in libc or libpthread examine multiple_thread + member of thread decriptor, otherwise return unconditionally 1. + 2002-12-14 Ulrich Drepper <drepper@redhat.com> * sysdeps/unix/sysv/linux/i386/pt-socket.S: Changes folded into the diff --git a/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h index ed9f9420e7..39bdfbea1d 100644 --- a/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h +++ b/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h @@ -19,11 +19,14 @@ #include <sysdep.h> #include <tls.h> +#ifndef ASSEMBLER +# include <nptl/pthreadP.h> +#endif #if !defined NOT_IN_libc || defined IS_IN_libpthread -#undef PSEUDO -#define PSEUDO(name, syscall_name, args) \ +# undef PSEUDO +# define PSEUDO(name, syscall_name, args) \ .text; \ ENTRY (name) \ cmpl $0, %gs:MULTIPLE_THREADS_OFFSET; \ @@ -33,7 +36,7 @@ jae SYSCALL_ERROR_LABEL; \ ret; \ L(pseudo_cancel): \ - call __libc_enable_asynccancel; \ + CENABLE \ SAVE_OLDTYPE_##args \ PUSHARGS_##args \ DOCARGS_##args \ @@ -45,26 +48,41 @@ jae SYSCALL_ERROR_LABEL; \ L(pseudo_end): -#define SAVE_OLDTYPE_0 movl %eax, %ecx; -#define SAVE_OLDTYPE_1 SAVE_OLDTYPE_0 -#define SAVE_OLDTYPE_2 pushl %eax; -#define SAVE_OLDTYPE_3 SAVE_OLDTYPE_2 -#define SAVE_OLDTYPE_4 SAVE_OLDTYPE_2 -#define SAVE_OLDTYPE_5 SAVE_OLDTYPE_2 +# define SAVE_OLDTYPE_0 movl %eax, %edx; +# define SAVE_OLDTYPE_1 SAVE_OLDTYPE_0 +# define SAVE_OLDTYPE_2 pushl %eax; +# define SAVE_OLDTYPE_3 SAVE_OLDTYPE_2 +# define SAVE_OLDTYPE_4 SAVE_OLDTYPE_2 +# define SAVE_OLDTYPE_5 SAVE_OLDTYPE_2 + +# define DOCARGS_0 DOARGS_0 +# define DOCARGS_1 DOARGS_1 +# define DOCARGS_2 _DOARGS_2 (12) +# define DOCARGS_3 _DOARGS_3 (20) +# define DOCARGS_4 _DOARGS_4 (28) +# define DOCARGS_5 _DOARGS_5 (36) + +# ifdef IS_IN_libpthread +# define CENABLE call __pthread_enable_asynccancel; +# define CDISABLE call __pthread_disable_asynccancel +# else +# define CENABLE call __libc_enable_asynccancel; +# define CDISABLE call __libc_disable_asynccancel +# endif +# define POPCARGS_0 pushl %eax; movl %ecx, %eax; CDISABLE; popl %eax; +# define POPCARGS_1 POPCARGS_0 +# define POPCARGS_2 xchgl (%esp), %eax; CDISABLE; popl %eax; +# define POPCARGS_3 POPCARGS_2 +# define POPCARGS_4 POPCARGS_2 +# define POPCARGS_5 POPCARGS_2 + +# define SINGLE_THREAD_P \ + __builtin_expect (THREAD_GETMEM (THREAD_SELF, \ + header.data.multiple_threads) == 0, 1) -#define DOCARGS_0 DOARGS_0 -#define DOCARGS_1 DOARGS_1 -#define DOCARGS_2 _DOARGS_2 (12) -#define DOCARGS_3 _DOARGS_3 (20) -#define DOCARGS_4 _DOARGS_4 (28) -#define DOCARGS_5 _DOARGS_5 (36) +#else -#define DISABLE call __libc_disable_asynccancel -#define POPCARGS_0 pushl %eax; movl %ecx, %eax; DISABLE; popl %eax; -#define POPCARGS_1 POPCARGS_0 -#define POPCARGS_2 xchgl (%esp), %eax; DISABLE; popl %eax; -#define POPCARGS_3 POPCARGS_2 -#define POPCARGS_4 POPCARGS_2 -#define POPCARGS_5 POPCARGS_2 +/* This code should never be used but we define it anyhow. */ +# define SINGLE_THREAD_P (1) #endif diff --git a/sysdeps/generic/pselect.c b/sysdeps/generic/pselect.c index 6aa60e8e72..e090d6e526 100644 --- a/sysdeps/generic/pselect.c +++ b/sysdeps/generic/pselect.c @@ -22,6 +22,7 @@ #include <stddef.h> /* For NULL. */ #include <sys/time.h> #include <sys/select.h> +#include <sysdep-cancel.h> /* Check the first NFDS descriptors each in READFDS (if not NULL) for read readiness, in WRITEFDS (if not NULL) for write readiness, and in EXCEPTFDS @@ -29,14 +30,9 @@ after waiting the interval specified therein. Additionally set the sigmask SIGMASK for this call. Returns the number of ready descriptors, or -1 for errors. */ -int -__pselect (nfds, readfds, writefds, exceptfds, timeout, sigmask) - int nfds; - fd_set *readfds; - fd_set *writefds; - fd_set *exceptfds; - const struct timespec *timeout; - const sigset_t *sigmask; +static int +do_pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + const struct timespec *timeout, const sigset_t *sigmask) { struct timeval tval; int retval; @@ -62,5 +58,28 @@ __pselect (nfds, readfds, writefds, exceptfds, timeout, sigmask) return retval; } + + +int +__pselect (nfds, readfds, writefds, exceptfds, timeout, sigmask) + int nfds; + fd_set *readfds; + fd_set *writefds; + fd_set *exceptfds; + const struct timespec *timeout; + const sigset_t *sigmask; +{ + if (SINGLE_THREAD_P) + return do_pselect (nfds, readfds, writefds, exceptfds, timeout, sigmask); + + int oldtype = LIBC_CANCEL_ASYNC (); + + int result = do_pselect (nfds, readfds, writefds, exceptfds, timeout, + sigmask); + + LIBC_CANCEL_RESET (oldtype); + + return result; +} weak_alias (__pselect, pselect) strong_alias (__pselect, __libc_pselect) diff --git a/sysdeps/generic/sysdep-cancel.h b/sysdeps/generic/sysdep-cancel.h index 0eca1e927c..f065e6e437 100644 --- a/sysdeps/generic/sysdep-cancel.h +++ b/sysdeps/generic/sysdep-cancel.h @@ -1 +1,6 @@ #include <sysdep.h> + +/* No multi-thread handling enabled. */ +#define SINGLE_THREAD_P (1) +#define LIBC_CANCEL_ASYNC() 0 /* Just a dummy value. */ +#define LIBC_CANCEL_RESET(val) /* Nothing. */ diff --git a/sysdeps/posix/open64.c b/sysdeps/posix/open64.c index 3db5292ff5..8d8bdbac55 100644 --- a/sysdeps/posix/open64.c +++ b/sysdeps/posix/open64.c @@ -19,6 +19,7 @@ #include <fcntl.h> #include <stdarg.h> #include <bp-sym.h> +#include <sysdep-cancel.h> /* Open FILE with access OFLAG. If OFLAG includes O_CREAT, a third argument is the file protection. */ @@ -35,7 +36,16 @@ __libc_open64 (const char *file, int oflag, ...) va_end (arg); } - return __libc_open (file, oflag | O_LARGEFILE, mode); + if (SINGLE_THREAD_P) + return __libc_open (file, oflag | O_LARGEFILE, mode); + + int oldtype = LIBC_CANCEL_ASYNC (); + + int result = __libc_open (file, oflag | O_LARGEFILE, mode); + + LIBC_CANCEL_RESET (oldtype); + + return result; } weak_alias (__libc_open64, BP_SYM (__open64)) libc_hidden_weak (BP_SYM (__open64)) diff --git a/sysdeps/posix/sigpause.c b/sysdeps/posix/sigpause.c index dba6912e90..e85a813ab0 100644 --- a/sysdeps/posix/sigpause.c +++ b/sysdeps/posix/sigpause.c @@ -19,13 +19,14 @@ #include <errno.h> #include <signal.h> #include <stddef.h> /* For NULL. */ +#include <sysdep-cancel.h> #include <sigset-cvt-mask.h> /* Set the mask of blocked signals to MASK, wait for a signal to arrive, and then restore the mask. */ -int -__sigpause (int sig_or_mask, int is_sig) +static int +do_sigpause (int sig_or_mask, int is_sig) { sigset_t set; @@ -42,6 +43,21 @@ __sigpause (int sig_or_mask, int is_sig) return __sigsuspend (&set); } + +int +__sigpause (int sig_or_mask, int is_sig) +{ + if (SINGLE_THREAD_P) + return do_sigpause (sig_or_mask, is_sig); + + int oldtype = LIBC_CANCEL_ASYNC (); + + int result = do_sigpause (sig_or_mask, is_sig); + + LIBC_CANCEL_RESET (oldtype); + + return result; +} libc_hidden_def (__sigpause) /* We have to provide a default version of this function since the diff --git a/sysdeps/posix/sigwait.c b/sysdeps/posix/sigwait.c index f2be3225c4..8b422d2b9d 100644 --- a/sysdeps/posix/sigwait.c +++ b/sysdeps/posix/sigwait.c @@ -1,5 +1,5 @@ /* Implementation of sigwait function from POSIX.1c. - Copyright (C) 1996, 1997, 1999, 2000 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -21,6 +21,7 @@ #include <errno.h> #include <signal.h> #include <stddef.h> /* For NULL. */ +#include <sysdep-cancel.h> /* This is our dummy signal handler we use here. */ static void ignore_signal (int sig); @@ -31,8 +32,8 @@ static void ignore_signal (int sig); static int was_sig; -int -__sigwait (const sigset_t *set, int *sig) +static int +do_sigwait (const sigset_t *set, int *sig) { sigset_t tmp_mask; struct sigaction saved[NSIG]; @@ -80,6 +81,22 @@ __sigwait (const sigset_t *set, int *sig) *sig = was_sig; return was_sig == -1 ? -1 : 0; } + + +int +__sigwait (const sigset_t *set, int *sig) +{ + if (SINGLE_THREAD_P) + return do_sigwait (set, sig); + + int oldtype = LIBC_CANCEL_ASYNC (); + + int result = do_sigwait (set, sig); + + LIBC_CANCEL_RESET (oldtype); + + return result; +} libc_hidden_def (__sigwait) weak_alias (__sigwait, sigwait) diff --git a/sysdeps/posix/system.c b/sysdeps/posix/system.c index 0881a3a431..bca1c2ec3e 100644 --- a/sysdeps/posix/system.c +++ b/sysdeps/posix/system.c @@ -24,6 +24,7 @@ #include <sys/types.h> #include <sys/wait.h> #include <bits/libc-lock.h> +#include <sysdep-cancel.h> #ifndef HAVE_GNU_LD @@ -185,6 +186,15 @@ __libc_system (const char *line) not be available after a chroot(), for example. */ return do_system ("exit 0") == 0; - return do_system (line); + if (SINGLE_THREAD_P) + return do_system (line); + + int oldtype = LIBC_CANCEL_ASYNC (); + + int result = do_system (line); + + LIBC_CANCEL_RESET (oldtype); + + return result; } weak_alias (__libc_system, system) diff --git a/sysdeps/posix/waitid.c b/sysdeps/posix/waitid.c index ef2ab2ed54..679d97d203 100644 --- a/sysdeps/posix/waitid.c +++ b/sysdeps/posix/waitid.c @@ -18,21 +18,18 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include <assert.h> #include <errno.h> #include <signal.h> #define __need_NULL #include <stddef.h> #include <sys/wait.h> #include <sys/types.h> +#include <sysdep-cancel.h> -#include <assert.h> -int -__waitid (idtype, id, infop, options) - idtype_t idtype; - id_t id; - siginfo_t *infop; - int options; +static int +do_waitid (idtype_t idtype, id_t id, siginfo_t *infop, int options) { pid_t pid, child; int status; @@ -118,5 +115,25 @@ __waitid (idtype, id, infop, options) return 0; } + + +int +__waitid (idtype, id, infop, options) + idtype_t idtype; + id_t id; |
