diff options
Diffstat (limited to 'lib/libpthread/uthread')
-rw-r--r-- | lib/libpthread/uthread/uthread_cancel.c | 164 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_close.c | 4 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_cond.c | 8 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_create.c | 7 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_fcntl.c | 5 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_fsync.c | 4 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_init.c | 4 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_join.c | 14 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_nanosleep.c | 4 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_open.c | 6 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_read.c | 10 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_sigwait.c | 6 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_wait4.c | 4 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_write.c | 10 |
14 files changed, 231 insertions, 19 deletions
diff --git a/lib/libpthread/uthread/uthread_cancel.c b/lib/libpthread/uthread/uthread_cancel.c new file mode 100644 index 00000000000..f3a205d1e9e --- /dev/null +++ b/lib/libpthread/uthread/uthread_cancel.c @@ -0,0 +1,164 @@ +/* + * David Leonard <d@openbsd.org>, 1999. Public domain. + */ +#include <sys/errno.h> +#include <pthread.h> +#include "pthread_private.h" + +int +pthread_cancel(pthread) + pthread_t pthread; +{ + int ret; + + if ((ret = _find_thread(pthread))) { + } else if (pthread->state == PS_DEAD) + ret = 0; + else { + /* Set the threads's I've-been-cancelled flag: */ + pthread->flags |= PTHREAD_CANCELLING; + /* Check if we need to kick it back into the run queue: */ + if ((pthread->cancelstate == PTHREAD_CANCEL_ENABLE) && + ((pthread->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS) || + (pthread->flags & PTHREAD_AT_CANCEL_POINT))) + switch (pthread->state) { + case PS_RUNNING: + /* No need to resume: */ + break; + case PS_WAIT_WAIT: + case PS_FDR_WAIT: + case PS_FDW_WAIT: + case PS_SLEEP_WAIT: + case PS_SELECT_WAIT: + case PS_SIGSUSPEND: + /* Interrupt and resume: */ + pthread->interrupted = 1; + PTHREAD_NEW_STATE(pthread,PS_RUNNING); + break; + case PS_MUTEX_WAIT: + case PS_COND_WAIT: + case PS_FDLR_WAIT: + case PS_FDLW_WAIT: + case PS_FILE_WAIT: + case PS_SIGWAIT: + case PS_JOIN: + case PS_SUSPENDED: + case PS_SIGTHREAD: + /* Simply wake: */ + /* XXX may be incorrect */ + PTHREAD_NEW_STATE(pthread,PS_RUNNING); + break; + case PS_DEAD: + case PS_STATE_MAX: + /* Ignore */ + break; + } + ret = 0; + } + return (ret); +} + +int +pthread_setcancelstate(state, oldstate) + int state; + int *oldstate; +{ + int ostate; + int ret; + + ostate = _thread_run->cancelstate; + + switch (state) { + case PTHREAD_CANCEL_ENABLE: + if (oldstate) + *oldstate = ostate; + _thread_run->cancelstate = PTHREAD_CANCEL_ENABLE; + if (_thread_run->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS) + _thread_cancellation_point(); + ret = 0; + break; + case PTHREAD_CANCEL_DISABLE: + if (oldstate) + *oldstate = ostate; + _thread_run->cancelstate = PTHREAD_CANCEL_DISABLE; + ret = 0; + break; + default: + ret = EINVAL; + } + + return (ret); +} + + +int +pthread_setcanceltype(type, oldtype) + int type; + int *oldtype; +{ + int otype; + int ret; + + otype = _thread_run->canceltype; + switch (type) { + case PTHREAD_CANCEL_ASYNCHRONOUS: + if (oldtype) + *oldtype = otype; + _thread_run->canceltype = PTHREAD_CANCEL_ASYNCHRONOUS; + _thread_cancellation_point(); + ret = 0; + break; + case PTHREAD_CANCEL_DEFERRED: + if (oldtype) + *oldtype = otype; + _thread_run->canceltype = PTHREAD_CANCEL_DEFERRED; + ret = 0; + break; + default: + ret = EINVAL; + } + + return (ret); +} + +void +pthread_testcancel() +{ + + _thread_cancellation_point(); +} + +void +_thread_enter_cancellation_point() +{ + + /* Look for a cancellation before we block: */ + _thread_cancellation_point(); + _thread_run->flags |= PTHREAD_AT_CANCEL_POINT; +} + +void +_thread_leave_cancellation_point() +{ + + _thread_run->flags &=~ PTHREAD_AT_CANCEL_POINT; + /* Look for a cancellation after we unblock: */ + _thread_cancellation_point(); +} + +/* + * Must only be called when in asynchronous cancel mode, or + * from pthread_testcancel(). + */ +void +_thread_cancellation_point() +{ + + if ((_thread_run->cancelstate == PTHREAD_CANCEL_ENABLE) && + ((_thread_run->flags & (PTHREAD_CANCELLING|PTHREAD_EXITING)) == + PTHREAD_CANCELLING)) { + _thread_run->flags &=~ PTHREAD_CANCELLING; + pthread_exit(PTHREAD_CANCELED); + PANIC("cancel"); + } +} diff --git a/lib/libpthread/uthread/uthread_close.c b/lib/libpthread/uthread/uthread_close.c index 7d95fbb3196..bc94d162b2a 100644 --- a/lib/libpthread/uthread/uthread_close.c +++ b/lib/libpthread/uthread/uthread_close.c @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: uthread_close.c,v 1.3 1999/01/06 05:29:22 d Exp $ + * $OpenBSD: uthread_close.c,v 1.4 1999/01/17 23:57:27 d Exp $ */ #include <stdlib.h> #include <unistd.h> @@ -46,6 +46,7 @@ close(int fd) int ret; struct stat sb; + _thread_enter_cancellation_point(); /* Lock the file descriptor while the file is closed: */ if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) { /* Get file descriptor status. */ @@ -84,6 +85,7 @@ close(int fd) free(_thread_fd_table[fd]); _thread_fd_table[fd] = NULL; } + _thread_leave_cancellation_point(); return (ret); } #endif diff --git a/lib/libpthread/uthread/uthread_cond.c b/lib/libpthread/uthread/uthread_cond.c index b2ef3df1ac5..525f86049b0 100644 --- a/lib/libpthread/uthread/uthread_cond.c +++ b/lib/libpthread/uthread/uthread_cond.c @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: uthread_cond.c,v 1.4 1999/01/06 05:29:22 d Exp $ + * $OpenBSD: uthread_cond.c,v 1.5 1999/01/17 23:57:27 d Exp $ */ #include <stdlib.h> #include <errno.h> @@ -137,6 +137,8 @@ pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex) */ else if (*cond != NULL || (rval = pthread_cond_init(cond,NULL)) == 0) { + _thread_enter_cancellation_point(); + /* Lock the condition variable structure: */ _SPINLOCK(&(*cond)->lock); @@ -185,6 +187,7 @@ pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex) break; } + _thread_leave_cancellation_point(); } /* Return the completion status: */ @@ -206,6 +209,7 @@ pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex, */ else if (*cond != NULL || (rval = pthread_cond_init(cond,NULL)) == 0) { + _thread_enter_cancellation_point(); /* Lock the condition variable structure: */ _SPINLOCK(&(*cond)->lock); @@ -263,7 +267,7 @@ pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex, rval = EINVAL; break; } - + _thread_leave_cancellation_point(); } /* Return the completion status: */ diff --git a/lib/libpthread/uthread/uthread_create.c b/lib/libpthread/uthread/uthread_create.c index 178c35424b8..1ed287d2b1b 100644 --- a/lib/libpthread/uthread/uthread_create.c +++ b/lib/libpthread/uthread/uthread_create.c @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: uthread_create.c,v 1.5 1999/01/06 05:29:22 d Exp $ + * $OpenBSD: uthread_create.c,v 1.6 1999/01/17 23:57:27 d Exp $ */ #include <errno.h> #include <stdlib.h> @@ -93,6 +93,9 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr, timerclear(&new_thread->ru_stime); _SPINUNLOCK(&new_thread->lock); + new_thread->cancelstate = PTHREAD_CANCEL_ENABLE; + new_thread->canceltype = PTHREAD_CANCEL_DEFERRED; + /* * Write a magic value to the thread structure * to help identify valid ones: @@ -109,7 +112,7 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr, new_thread->sigmask = _thread_run->sigmask; /* Initialise the jump buffer: */ - setjmp(new_thread->saved_jmp_buf); + _thread_machdep_setjmp(new_thread->saved_jmp_buf); /* * Set up new stack frame so that it looks like it diff --git a/lib/libpthread/uthread/uthread_fcntl.c b/lib/libpthread/uthread/uthread_fcntl.c index e7e11a2e218..1a0a3e9548a 100644 --- a/lib/libpthread/uthread/uthread_fcntl.c +++ b/lib/libpthread/uthread/uthread_fcntl.c @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: uthread_fcntl.c,v 1.3 1999/01/06 05:29:23 d Exp $ + * $OpenBSD: uthread_fcntl.c,v 1.4 1999/01/17 23:57:27 d Exp $ */ #include <stdarg.h> #include <unistd.h> @@ -47,6 +47,8 @@ fcntl(int fd, int cmd,...) int ret; va_list ap; + _thread_enter_cancellation_point(); + /* Lock the file descriptor: */ if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) { /* Initialise the variable argument list: */ @@ -135,6 +137,7 @@ fcntl(int fd, int cmd,...) /* Unlock the file descriptor: */ _FD_UNLOCK(fd, FD_RDWR); } + _thread_leave_cancellation_point(); /* Return the completion status: */ return (ret); diff --git a/lib/libpthread/uthread/uthread_fsync.c b/lib/libpthread/uthread/uthread_fsync.c index 4c953443e95..9db34f5564c 100644 --- a/lib/libpthread/uthread/uthread_fsync.c +++ b/lib/libpthread/uthread/uthread_fsync.c @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: uthread_fsync.c,v 1.2 1999/01/06 05:29:24 d Exp $ + * $OpenBSD: uthread_fsync.c,v 1.3 1999/01/17 23:57:27 d Exp $ */ #include <unistd.h> #ifdef _THREAD_SAFE @@ -41,10 +41,12 @@ fsync(int fd) { int ret; + _thread_enter_cancellation_point(); if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) { ret = _thread_sys_fsync(fd); _FD_UNLOCK(fd, FD_RDWR); } + _thread_leave_cancellation_point(); return (ret); } #endif diff --git a/lib/libpthread/uthread/uthread_init.c b/lib/libpthread/uthread/uthread_init.c index ad56b9a670c..0cd5bd376c4 100644 --- a/lib/libpthread/uthread/uthread_init.c +++ b/lib/libpthread/uthread/uthread_init.c @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: uthread_init.c,v 1.7 1999/01/10 23:11:33 d Exp $ + * $OpenBSD: uthread_init.c,v 1.8 1999/01/17 23:57:27 d Exp $ */ #include <errno.h> @@ -224,6 +224,8 @@ _thread_init(void) _thread_initial->nxt = NULL; _thread_initial->flags = 0; _thread_initial->error = 0; + _thread_initial->cancelstate = PTHREAD_CANCEL_ENABLE; + _thread_initial->canceltype = PTHREAD_CANCEL_DEFERRED; _thread_initial->magic = PTHREAD_MAGIC; pthread_set_name_np(_thread_initial, "init"); _SPINUNLOCK(&_thread_initial->lock); diff --git a/lib/libpthread/uthread/uthread_join.c b/lib/libpthread/uthread/uthread_join.c index 9602ec52a25..52baee31c33 100644 --- a/lib/libpthread/uthread/uthread_join.c +++ b/lib/libpthread/uthread/uthread_join.c @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: uthread_join.c,v 1.2 1999/01/06 05:29:24 d Exp $ + * $OpenBSD: uthread_join.c,v 1.3 1999/01/17 23:57:27 d Exp $ */ #include <errno.h> #ifdef _THREAD_SAFE @@ -42,15 +42,21 @@ pthread_join(pthread_t pthread, void **thread_return) int ret = 0; pthread_t pthread1 = NULL; + _thread_enter_cancellation_point(); + /* Check if the caller has specified an invalid thread: */ - if (pthread == NULL || pthread->magic != PTHREAD_MAGIC) + if (pthread == NULL || pthread->magic != PTHREAD_MAGIC) { /* Invalid thread: */ + _thread_leave_cancellation_point(); return(EINVAL); + } /* Check if the caller has specified itself: */ - if (pthread == _thread_run) + if (pthread == _thread_run) { /* Avoid a deadlock condition: */ + _thread_leave_cancellation_point(); return(EDEADLK); + } /* * Find the thread in the list of active threads or in the @@ -93,6 +99,8 @@ pthread_join(pthread_t pthread, void **thread_return) /* Return the thread's return value: */ *thread_return = pthread->ret; + _thread_leave_cancellation_point(); + /* Return the completion status: */ return (ret); } diff --git a/lib/libpthread/uthread/uthread_nanosleep.c b/lib/libpthread/uthread/uthread_nanosleep.c index 450b505bf12..0f5c4c9c2ab 100644 --- a/lib/libpthread/uthread/uthread_nanosleep.c +++ b/lib/libpthread/uthread/uthread_nanosleep.c @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: uthread_nanosleep.c,v 1.2 1999/01/06 05:29:25 d Exp $ + * $OpenBSD: uthread_nanosleep.c,v 1.3 1999/01/17 23:57:27 d Exp $ */ #include <stdio.h> #include <errno.h> @@ -48,6 +48,7 @@ nanosleep(const struct timespec * time_to_sleep, struct timespec remaining_time; struct timeval tv; + _thread_enter_cancellation_point(); /* Check if the time to sleep is legal: */ if (time_to_sleep == NULL || time_to_sleep->tv_nsec < 0 || time_to_sleep->tv_nsec > 1000000000 || time_to_sleep->tv_sec < 0) { /* Return an EINVAL error : */ @@ -95,6 +96,7 @@ nanosleep(const struct timespec * time_to_sleep, ret = -1; } } + _thread_leave_cancellation_point(); return (ret); } #endif diff --git a/lib/libpthread/uthread/uthread_open.c b/lib/libpthread/uthread/uthread_open.c index 52d0a6b06cf..9c03daa4f47 100644 --- a/lib/libpthread/uthread/uthread_open.c +++ b/lib/libpthread/uthread/uthread_open.c @@ -30,7 +30,7 @@ * SUCH DAMAGE. * * $FreeBSD: uthread_open.c,v 1.4 1998/04/29 09:59:07 jb Exp $ - * $OpenBSD: uthread_open.c,v 1.2 1998/12/23 22:49:46 d Exp $ + * $OpenBSD: uthread_open.c,v 1.3 1999/01/17 23:57:27 d Exp $ * */ #include <stdarg.h> @@ -49,6 +49,8 @@ open(const char *path, int flags,...) int mode = 0; va_list ap; + _thread_enter_cancellation_point(); + /* Check if the file is being created: */ if (flags & O_CREAT) { /* Get the creation mode: */ @@ -68,6 +70,8 @@ open(const char *path, int flags,...) fd = -1; } + _thread_leave_cancellation_point(); + /* Return the file descriptor or -1 on error: */ return (fd); } diff --git a/lib/libpthread/uthread/uthread_read.c b/lib/libpthread/uthread/uthread_read.c index 37b0c9067bb..22d1d03f091 100644 --- a/lib/libpthread/uthread/uthread_read.c +++ b/lib/libpthread/uthread/uthread_read.c @@ -30,7 +30,7 @@ * SUCH DAMAGE. * * $FreeBSD: uthread_read.c,v 1.6 1998/06/10 22:28:43 jb Exp $ - * $OpenBSD: uthread_read.c,v 1.2 1998/12/23 22:49:46 d Exp $ + * $OpenBSD: uthread_read.c,v 1.3 1999/01/17 23:57:27 d Exp $ * */ #include <sys/types.h> @@ -48,9 +48,13 @@ read(int fd, void *buf, size_t nbytes) int ret; int type; + _thread_enter_cancellation_point(); + /* POSIX says to do just this: */ - if (nbytes == 0) + if (nbytes == 0) { + _thread_leave_cancellation_point(); return (0); + } /* Lock the file descriptor for read: */ if ((ret = _FD_LOCK(fd, FD_READ, NULL)) == 0) { @@ -62,6 +66,7 @@ read(int fd, void *buf, size_t nbytes) /* File is not open for read: */ errno = EBADF; _FD_UNLOCK(fd, FD_READ); + _thread_leave_cancellation_point(); return (-1); } @@ -93,6 +98,7 @@ read(int fd, void *buf, size_t nbytes) } _FD_UNLOCK(fd, FD_READ); } + _thread_leave_cancellation_point(); return (ret); } #endif diff --git a/lib/libpthread/uthread/uthread_sigwait.c b/lib/libpthread/uthread/uthread_sigwait.c index 8432e879646..3593b72853f 100644 --- a/lib/libpthread/uthread/uthread_sigwait.c +++ b/lib/libpthread/uthread/uthread_sigwait.c @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: uthread_sigwait.c,v 1.3 1999/01/06 05:29:28 d Exp $ + * $OpenBSD: uthread_sigwait.c,v 1.4 1999/01/17 23:57:27 d Exp $ */ #include <signal.h> #include <errno.h> @@ -45,6 +45,7 @@ sigwait(const sigset_t * set, int *sig) sigset_t tempset; struct sigaction act; + _thread_enter_cancellation_point(); /* * Specify the thread kernel signal handler. */ @@ -75,6 +76,7 @@ sigwait(const sigset_t * set, int *sig) /* Return the signal number to the caller: */ *sig = i; + _thread_leave_cancellation_point(); return (0); } @@ -127,6 +129,8 @@ sigwait(const sigset_t * set, int *sig) } } + _thread_leave_cancellation_point(); + /* Return the completion status: */ return (ret); } diff --git a/lib/libpthread/uthread/uthread_wait4.c b/lib/libpthread/uthread/uthread_wait4.c index 5017fe5c1ac..a4f44e1d405 100644 --- a/lib/libpthread/uthread/uthread_wait4.c +++ b/lib/libpthread/uthread/uthread_wait4.c @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: uthread_wait4.c,v 1.2 1999/01/06 05:29:29 d Exp $ + * $OpenBSD: uthread_wait4.c,v 1.3 1999/01/17 23:57:28 d Exp $ */ #include <errno.h> #include <sys/wait.h> @@ -42,6 +42,7 @@ wait4(pid_t pid, int *istat, int options, struct rusage * rusage) { pid_t ret; + _thread_enter_cancellation_point(); /* Perform a non-blocking wait4 syscall: */ while ((ret = _thread_sys_wait4(pid, istat, options | WNOHANG, rusage)) == 0 && (options & WNOHANG) == 0) { /* Reset the interrupted operation flag: */ @@ -57,6 +58,7 @@ wait4(pid_t pid, int *istat, int options, struct rusage * rusage) break; } } + _thread_leave_cancellation_point(); return (ret); } #endif diff --git a/lib/libpthread/uthread/uthread_write.c b/lib/libpthread/uthread/uthread_write.c index ba8585ec8b2..b7c974ee289 100644 --- a/lib/libpthread/uthread/uthread_write.c +++ b/lib/libpthread/uthread/uthread_write.c @@ -30,7 +30,7 @@ * SUCH DAMAGE. * * $FreeBSD: uthread_write.c,v 1.10 1998/09/07 21:55:01 alex Exp $ - * $OpenBSD: uthread_write.c,v 1.2 1998/12/23 22:49:47 d Exp $ + * $OpenBSD: uthread_write.c,v 1.3 1999/01/17 23:57:28 d Exp $ * */ #include <sys/types.h> @@ -51,9 +51,13 @@ write(int fd, const void *buf, size_t nbytes) ssize_t num = 0; ssize_t ret; + _thread_enter_cancellation_point(); + /* POSIX says to do just this: */ - if (nbytes == 0) + if (nbytes == 0) { + _thread_leave_cancellation_point(); return (0); + } /* Lock the file descriptor for write: */ if ((ret = _FD_LOCK(fd, FD_WRITE, NULL)) == 0) { @@ -65,6 +69,7 @@ write(int fd, const void *buf, size_t nbytes) /* File is not open for write: */ errno = EBADF; _FD_UNLOCK(fd, FD_WRITE); + _thread_leave_cancellation_point(); return (-1); } @@ -130,6 +135,7 @@ write(int fd, const void *buf, size_t nbytes) } _FD_UNLOCK(fd, FD_RDWR); } + _thread_leave_cancellation_point(); return (ret); } #endif |