diff options
author | julian <julian@FreeBSD.org> | 1998-02-13 01:27:34 +0000 |
---|---|---|
committer | julian <julian@FreeBSD.org> | 1998-02-13 01:27:34 +0000 |
commit | b31dde27bfeaed94b1026c0788c4e98b1af47f3c (patch) | |
tree | fc79071c0e7ec3b06afa547a18a7327d4c544935 /lib/libc_r | |
parent | b28763a6b13c1f0830c84238266c8ad69f7455bd (diff) | |
download | FreeBSD-src-b31dde27bfeaed94b1026c0788c4e98b1af47f3c.zip FreeBSD-src-b31dde27bfeaed94b1026c0788c4e98b1af47f3c.tar.gz |
Fixes from Jeremy Allison and Terry Lambert for pthreads:
specifically:
uthread_accept.c: Fix for inherited socket not getting correct entry in
pthread flags.
uthread_create.c: Fix to allow pthread_t pointer return to be null if
caller doesn't care about return.
uthread_fd.c: Fix for return codes to be placed into correct errno.
uthread_init.c: Changes to make gcc-2.8 thread aware for exception stack
frames (WARNING: This is #ifdef'ed out by default and is
different from the Cygnus egcs fix).
uthread_ioctl.c: Fix for blocking/non-blocking ioctl.
uthread_kern.c: Signal handling fixes (only one case left to fix,
that of an externally sent SIGSEGV and friends -
a fairly unusual case).
uthread_write.c: Fix for lock of fd - ask for write lock, not read/write.
uthread_writev.c: Fix for lock of fd - ask for write lock, not read/write.
Pthreads now works well enough to run the LDAP and ACAPD(with the gcc 2.8 fix)
sample implementations.
Diffstat (limited to 'lib/libc_r')
-rw-r--r-- | lib/libc_r/uthread/uthread_accept.c | 3 | ||||
-rw-r--r-- | lib/libc_r/uthread/uthread_create.c | 3 | ||||
-rw-r--r-- | lib/libc_r/uthread/uthread_fd.c | 32 | ||||
-rw-r--r-- | lib/libc_r/uthread/uthread_init.c | 36 | ||||
-rw-r--r-- | lib/libc_r/uthread/uthread_ioctl.c | 39 | ||||
-rw-r--r-- | lib/libc_r/uthread/uthread_kern.c | 54 | ||||
-rw-r--r-- | lib/libc_r/uthread/uthread_write.c | 6 | ||||
-rw-r--r-- | lib/libc_r/uthread/uthread_writev.c | 6 |
8 files changed, 154 insertions, 25 deletions
diff --git a/lib/libc_r/uthread/uthread_accept.c b/lib/libc_r/uthread/uthread_accept.c index 1078bfe..261fa15 100644 --- a/lib/libc_r/uthread/uthread_accept.c +++ b/lib/libc_r/uthread/uthread_accept.c @@ -94,12 +94,11 @@ accept(int fd, struct sockaddr * name, int *namelen) * set the new socket flags to non-blocking, as that * will be the inherited state of the new socket. */ - if((_thread_fd_table[fd]->flags & O_NONBLOCK) == 0) + if((ret > 0) && (_thread_fd_table[fd]->flags & O_NONBLOCK) == 0) _thread_fd_table[ret]->flags &= ~O_NONBLOCK; /* Unlock the file descriptor: */ _thread_fd_unlock(fd, FD_RDWR); - } /* Return the socket file descriptor or -1 on error: */ return (ret); diff --git a/lib/libc_r/uthread/uthread_create.c b/lib/libc_r/uthread/uthread_create.c index e4925a9..398ff21 100644 --- a/lib/libc_r/uthread/uthread_create.c +++ b/lib/libc_r/uthread/uthread_create.c @@ -199,7 +199,8 @@ _thread_create(pthread_t * thread, const pthread_attr_t * attr, _thread_link_list = new_thread; /* Return a pointer to the thread structure: */ - (*thread) = new_thread; + if(thread) + (*thread) = new_thread; /* Check if a parent thread was specified: */ if (parent != NULL) { diff --git a/lib/libc_r/uthread/uthread_fd.c b/lib/libc_r/uthread/uthread_fd.c index 1e61bb7..541f92f 100644 --- a/lib/libc_r/uthread/uthread_fd.c +++ b/lib/libc_r/uthread/uthread_fd.c @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: uthread_fd.c,v 1.4 1997/04/01 22:49:58 jb Exp $ * */ #include <errno.h> @@ -39,6 +39,13 @@ #include <pthread.h> #include "pthread_private.h" +/* + * This function *must* return -1 and set the thread specific errno + * as a system call. This is because the error return from this + * function is propagated directly back from thread-wrapped system + * calls. + */ + int _thread_fd_table_init(int fd) { @@ -49,9 +56,11 @@ _thread_fd_table_init(int fd) _thread_kern_sig_block(&status); /* Check if the file descriptor is out of range: */ - if (fd < 0 || fd >= _thread_dtablesize) + if (fd < 0 || fd >= _thread_dtablesize) { /* Return a bad file descriptor error: */ - ret = EBADF; + errno = EBADF; + ret = -1; + } /* * Check if memory has already been allocated for this file @@ -62,9 +71,11 @@ _thread_fd_table_init(int fd) } /* Allocate memory for the file descriptor table entry: */ else if ((_thread_fd_table[fd] = (struct fd_table_entry *) - malloc(sizeof(struct fd_table_entry))) == NULL) + malloc(sizeof(struct fd_table_entry))) == NULL) { /* Return a bad file descriptor error: */ - ret = EBADF; + errno = EBADF; + ret = -1; + } else { /* Assume that the operation will succeed: */ ret = 0; @@ -85,9 +96,9 @@ _thread_fd_table_init(int fd) /* Get the flags for the file: */ if (fd >= 3 && (_thread_fd_table[fd]->flags = - _thread_sys_fcntl(fd, F_GETFL, 0)) == -1) - ret = errno; - + _thread_sys_fcntl(fd, F_GETFL, 0)) == -1) { + ret = -1; + } else { /* Check if a stdio descriptor: */ if (fd < 3) @@ -109,8 +120,9 @@ _thread_fd_table_init(int fd) * Some devices don't support * non-blocking calls (sigh): */ - if (errno != ENODEV) - ret = errno; + if (errno != ENODEV) { + ret = -1; + } } } diff --git a/lib/libc_r/uthread/uthread_init.c b/lib/libc_r/uthread/uthread_init.c index 5833cdf..78967f4 100644 --- a/lib/libc_r/uthread/uthread_init.c +++ b/lib/libc_r/uthread/uthread_init.c @@ -46,6 +46,31 @@ #include "pthread_private.h" extern int _thread_autoinit_dummy_decl; +#ifdef GCC_2_8_MADE_THREAD_AWARE +typedef void *** (*dynamic_handler_allocator)(); +extern void __set_dynamic_handler_allocator(dynamic_handler_allocator); + +static pthread_key_t except_head_key; + +typedef struct { + void **__dynamic_handler_chain; + void *top_elt[2]; +} except_struct; + +static void ***dynamic_allocator_handler_fn() +{ + except_struct *dh = (except_struct *)pthread_getspecific(except_head_key); + + if(dh == NULL) { + dh = (except_struct *)malloc( sizeof(except_struct) ); + memset(dh, '\0', sizeof(except_struct)); + dh->__dynamic_handler_chain= dh->top_elt; + pthread_setspecific(except_head_key, (void *)dh); + } + return &dh->__dynamic_handler_chain; +} +#endif /* GCC_2_8_MADE_THREAD_AWARE */ + /* * Threaded process initialization */ @@ -55,7 +80,6 @@ _thread_init(void) int flags; int i; struct sigaction act; - /* Ensure that the auto-initialization routine is linked in: */ _thread_autoinit_dummy_decl = 1; @@ -200,6 +224,16 @@ _thread_init(void) } } } + +#ifdef GCC_2_8_MADE_THREAD_AWARE + /* Create the thread-specific data for the exception linked list. */ + if(pthread_key_create(&except_head_key, NULL) != 0) + PANIC("Failed to create thread specific execption head"); + + /* Setup the gcc exception handler per thread. */ + __set_dynamic_handler_allocator( dynamic_allocator_handler_fn ); +#endif /* GCC_2_8_MADE_THREAD_AWARE */ + return; } diff --git a/lib/libc_r/uthread/uthread_ioctl.c b/lib/libc_r/uthread/uthread_ioctl.c index 69df24d..676eff3 100644 --- a/lib/libc_r/uthread/uthread_ioctl.c +++ b/lib/libc_r/uthread/uthread_ioctl.c @@ -33,6 +33,7 @@ #include <stdarg.h> #include <sys/ioctl.h> #ifdef _THREAD_SAFE +#include <sys/fcntl.h> /* O_NONBLOCK*/ #include <pthread.h> #include "pthread_private.h" @@ -40,14 +41,44 @@ int ioctl(int fd, unsigned long request,...) { int ret; + int *op; + int status; va_list ap; + /* Block signals: */ + _thread_kern_sig_block(&status); + + /* Lock the file descriptor: */ + if ((ret = _thread_fd_lock(fd, FD_RDWR, NULL, __FILE__, __LINE__)) == 0) { + /* Initialise the variable argument list: */ va_start(ap, request); - if (fd < 0 || fd >= _thread_dtablesize) - ret = -1; - else + + switch( request) { + case FIONBIO: + /* + * descriptors must be non-blocking; we are only + * twiddling the flag based on the request + */ + op = va_arg(ap, int *); + _thread_fd_table[fd]->flags &= ~O_NONBLOCK; + _thread_fd_table[fd]->flags |= ((*op) ? O_NONBLOCK : 0); + ret = 0; + break; + default: ret = _thread_sys_ioctl(fd, request, va_arg(ap, char *)); + break; + } + + /* Free variable arguments: */ va_end(ap); - return ret; + + /* Unlock the file descriptor: */ + _thread_fd_unlock(fd, FD_RDWR); + } + /* Unblock signals: */ + _thread_kern_sig_unblock(status); + + /* Return the completion status: */ + return (ret); } #endif diff --git a/lib/libc_r/uthread/uthread_kern.c b/lib/libc_r/uthread/uthread_kern.c index ba8e250..925d5bf 100644 --- a/lib/libc_r/uthread/uthread_kern.c +++ b/lib/libc_r/uthread/uthread_kern.c @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: uthread_kern.c,v 1.5 1997/04/01 22:51:48 jb Exp $ * */ #include <errno.h> @@ -949,6 +949,58 @@ _thread_signal(pthread_t pthread, int sig) _thread_sys_sigreturn(&pthread->saved_sigcontext); break; + /* + * The following signals should terminate the + * process. Do this by clearing the signal action + * and then re-throwing the signal. + */ + case SIGHUP: + case SIGINT: + case SIGPIPE: + case SIGALRM: + case SIGTERM: + case SIGXCPU: + case SIGXFSZ: + case SIGVTALRM: + case SIGUSR1: + case SIGUSR2: + /* These signals stop the process. Also re-throw them. */ + case SIGTSTP: + case SIGTTIN: + case SIGTTOU: + /* Clear the signal action: */ + sigfillset(&act.sa_mask); + act.sa_handler = SIG_DFL; + act.sa_flags = SA_RESTART; + _thread_sys_sigaction(sig, &act, NULL); + /* Re-throw to ourselves. */ + kill(getpid(), sig); + break; + + case SIGCONT: + /* + * If we get this it means that we were + * probably stopped and then continued. + * Reset the handler for the SIGTSTP, SIGTTIN + * and SIGTTOU signals. + */ + + sigfillset(&act.sa_mask); + act.sa_handler = (void (*) ()) _thread_sig_handler; + act.sa_flags = SA_RESTART; + + /* Initialise the signals for default handling: */ + if (_thread_sys_sigaction(SIGTSTP, &act, NULL) != 0) { + PANIC("Cannot initialise SIGTSTP signal handler"); + } + if (_thread_sys_sigaction(SIGTTIN, &act, NULL) != 0) { + PANIC("Cannot initialise SIGTTIN signal handler"); + } + if (_thread_sys_sigaction(SIGTTOU, &act, NULL) != 0) { + PANIC("Cannot initialise SIGTTOU signal handler"); + } + break; + /* Default processing for other signals: */ default: /* diff --git a/lib/libc_r/uthread/uthread_write.c b/lib/libc_r/uthread/uthread_write.c index eab105d..e86e71b 100644 --- a/lib/libc_r/uthread/uthread_write.c +++ b/lib/libc_r/uthread/uthread_write.c @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: uthread_write.c,v 1.3 1997/04/01 22:44:17 jb Exp $ * */ #include <sys/types.h> @@ -47,8 +47,8 @@ write(int fd, const void *buf, size_t nbytes) int ret; int status; - /* Lock the file descriptor for read and write: */ - if ((ret = _thread_fd_lock(fd, FD_RDWR, NULL, + /* Lock the file descriptor for write: */ + if ((ret = _thread_fd_lock(fd, FD_WRITE, NULL, __FILE__, __LINE__)) == 0) { /* Perform a non-blocking write syscall: */ while ((ret = _thread_sys_write(fd, buf, nbytes)) < 0) { diff --git a/lib/libc_r/uthread/uthread_writev.c b/lib/libc_r/uthread/uthread_writev.c index 5ad1ce9..56e1872 100644 --- a/lib/libc_r/uthread/uthread_writev.c +++ b/lib/libc_r/uthread/uthread_writev.c @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: uthread_writev.c,v 1.3 1997/04/01 22:44:18 jb Exp $ * */ #include <sys/types.h> @@ -47,8 +47,8 @@ writev(int fd, const struct iovec * iov, int iovcnt) int ret; int status; - /* Lock the file descriptor for read and write: */ - if ((ret = _thread_fd_lock(fd, FD_RDWR, NULL, + /* Lock the file descriptor for write: */ + if ((ret = _thread_fd_lock(fd, FD_WRITE, NULL, __FILE__, __LINE__)) == 0) { /* Perform a non-blocking writev syscall: */ while ((ret = _thread_sys_writev(fd, iov, iovcnt)) < 0) { |