From b31dde27bfeaed94b1026c0788c4e98b1af47f3c Mon Sep 17 00:00:00 2001 From: julian Date: Fri, 13 Feb 1998 01:27:34 +0000 Subject: 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. --- lib/libpthread/thread/thr_create.c | 3 ++- lib/libpthread/thread/thr_init.c | 36 ++++++++++++++++++++++++- lib/libpthread/thread/thr_kern.c | 54 +++++++++++++++++++++++++++++++++++++- lib/libpthread/thread/thr_write.c | 6 ++--- lib/libpthread/thread/thr_writev.c | 6 ++--- 5 files changed, 96 insertions(+), 9 deletions(-) (limited to 'lib/libpthread') diff --git a/lib/libpthread/thread/thr_create.c b/lib/libpthread/thread/thr_create.c index e4925a9..398ff21 100644 --- a/lib/libpthread/thread/thr_create.c +++ b/lib/libpthread/thread/thr_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/libpthread/thread/thr_init.c b/lib/libpthread/thread/thr_init.c index 5833cdf..78967f4 100644 --- a/lib/libpthread/thread/thr_init.c +++ b/lib/libpthread/thread/thr_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/libpthread/thread/thr_kern.c b/lib/libpthread/thread/thr_kern.c index ba8e250..925d5bf 100644 --- a/lib/libpthread/thread/thr_kern.c +++ b/lib/libpthread/thread/thr_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 @@ -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/libpthread/thread/thr_write.c b/lib/libpthread/thread/thr_write.c index eab105d..e86e71b 100644 --- a/lib/libpthread/thread/thr_write.c +++ b/lib/libpthread/thread/thr_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 @@ -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/libpthread/thread/thr_writev.c b/lib/libpthread/thread/thr_writev.c index 5ad1ce9..56e1872 100644 --- a/lib/libpthread/thread/thr_writev.c +++ b/lib/libpthread/thread/thr_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 @@ -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) { -- cgit v1.1