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.
This commit is contained in:
parent
a896b1129f
commit
f0af3bec3a
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
/*
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
/*
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
/*
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user