diff options
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | create.c | 3 | ||||
-rw-r--r-- | pthread.h | 26 | ||||
-rw-r--r-- | signal.c | 65 |
4 files changed, 110 insertions, 0 deletions
@@ -1,3 +1,19 @@ +1998-07-24 Ben Elliston <bje@cygnus.com> + + * pthread.h (SIG_BLOCK): Define if not already defined. + (SIG_UNBLOCK): Likewise. + (SIG_SETMASK): Likewise. + (pthread_attr_t): Add signal mask member. + (pthread_sigmask): Add function prototype. + + * signal.c (pthread_sigmask): Implement. + + * create.c: #include <string.h> to get a prototype for memcpy(). + (pthread_create): New threads inherit their creator's signal + mask. Copy the signal mask to the new thread structure. + + + Fri Jul 24 16:33:17 1998 Ross Johnson <rpj@swan.canberra.edu.au> * fork.c (pthread_atfork): Add all the necessary push calls. @@ -8,6 +8,8 @@ #include <windows.h> #include <process.h> +#include <string.h> + #include "pthread.h" #include "implement.h" @@ -84,6 +86,7 @@ pthread_create(pthread_t *thread, attr_copy->canceltype = attr->canceltype; attr_copy->detached = attr->detached; attr_copy->priority = attr->priority; + memcpy(attr_copy.sigmask, attr.sigmask, sizeof(sigset_t)); } /* Start running, not suspended. */ @@ -22,6 +22,22 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef _PTHREADS_H #define _PTHREADS_H +#ifdef HAVE_SIGNAL_H +#include <signal.h> +#endif /* HAVE_SIGNAL_H */ + +#ifndef SIG_BLOCK +#define SIG_BLOCK 0 +#endif /* SIG_BLOCK */ + +#ifndef SIG_UNBLOCK +#define SIG_BLOCK 1 +#endif /* SIG_UNBLOCK */ + +#ifndef SIG_SETMASK +#define SIG_SETMASK 2 +#endif /* SIG_SETMASK */ + #define PTHREAD_THREADS_MAX 128 #define PTHREAD_STACK_MIN 65535 @@ -72,6 +88,10 @@ typedef struct { int canceltype; /* PTHREAD_CANCEL_ASYNCHRONOUS PTHREAD_CANCEL_DEFERRED */ +#ifdef HAVE_SIGSET_T + sigset_t sigmask; +#endif /* HAVE_SIGSET_T */ + int priority; } pthread_attr_t; @@ -243,6 +263,12 @@ void *pthread_getspecific(pthread_key_t key); int pthread_key_delete(pthread_key_t key); +/* Signal handling. */ + +int pthread_sigmask(int how, + const sigset_t *set, + sigset_t *oset); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/signal.c b/signal.c new file mode 100644 index 0000000..e0a41ca --- /dev/null +++ b/signal.c @@ -0,0 +1,65 @@ +/* + * signal.c + * + * Description: + * POSIX thread-aware signal functions. + */ + +#include "pthread.h" + +int +pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) +{ + /* Validate the `how' argument.*/ + if (set != NULL) + { + switch (how) + { + case SIG_BLOCK: + break; + case SIG_UNBLOCK: + break; + case SIG_SETMASK: + break; + default: + /* Invalid `how' argument. */ + return EINVAL; + } + } + + /* Copy the old mask before modifying it. */ + if (oset != NULL) + { + memcpy(oset, this->attr->sigmask, sizeof(sigset_t)); + } + + if (set != NULL) + { + int i; + unsigned long *src = set; + unsigned long *dest = this->attr->sigmask; + + switch (how) + { + case SIG_BLOCK: + for (i = 0; i < (sizeof(sigset_t) / sizeof(unsigned long)); i++) + { + /* OR the bit field longword-wise. */ + *src++ |= *dest++; + } + break; + case SIG_UNBLOCK: + for (i = 0; i < (sizeof(sigset_t) / sizeof(unsigned long)); i++) + { + /* XOR the bitfield longword-wise. */ + *src++ ^= *dest++; + } + case SIG_SET: + /* Replace the whole sigmask. */ + memcpy(this->attr.sigmask, set, sizeof(sigset_t)); + break; + } + } + + return 0; +} |