summaryrefslogtreecommitdiffstats
path: root/lib/libc_r
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>1998-02-13 01:27:34 +0000
committerjulian <julian@FreeBSD.org>1998-02-13 01:27:34 +0000
commitb31dde27bfeaed94b1026c0788c4e98b1af47f3c (patch)
treefc79071c0e7ec3b06afa547a18a7327d4c544935 /lib/libc_r
parentb28763a6b13c1f0830c84238266c8ad69f7455bd (diff)
downloadFreeBSD-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.c3
-rw-r--r--lib/libc_r/uthread/uthread_create.c3
-rw-r--r--lib/libc_r/uthread/uthread_fd.c32
-rw-r--r--lib/libc_r/uthread/uthread_init.c36
-rw-r--r--lib/libc_r/uthread/uthread_ioctl.c39
-rw-r--r--lib/libc_r/uthread/uthread_kern.c54
-rw-r--r--lib/libc_r/uthread/uthread_write.c6
-rw-r--r--lib/libc_r/uthread/uthread_writev.c6
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) {
OpenPOWER on IntegriCloud