diff options
-rw-r--r-- | lib/librthread/Makefile | 5 | ||||
-rw-r--r-- | lib/librthread/rthread.c | 44 | ||||
-rw-r--r-- | lib/librthread/rthread.h | 11 | ||||
-rw-r--r-- | lib/librthread/rthread_cancel.c | 524 | ||||
-rw-r--r-- | lib/librthread/rthread_libc.c | 191 | ||||
-rw-r--r-- | lib/librthread/rthread_sig.c | 9 |
6 files changed, 583 insertions, 201 deletions
diff --git a/lib/librthread/Makefile b/lib/librthread/Makefile index bdc89260880..5716a110a63 100644 --- a/lib/librthread/Makefile +++ b/lib/librthread/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.18 2011/11/27 04:12:43 guenther Exp $ +# $OpenBSD: Makefile,v 1.19 2011/12/05 04:02:03 guenther Exp $ LIB=rthread WANTLINT= @@ -13,7 +13,8 @@ LDADD = -Wl,-znodelete,-zinitfirst .PATH: ${.CURDIR}/arch/${MACHINE_CPU} SRCS= rthread.c rthread_attr.c rthread_sched.c rthread_sync.c rthread_tls.c \ rthread_sig.c rthread_np.c rthread_debug.c rthread_stack.c \ - rthread_libc.c rthread_fork.c rthread_file.c sched_prio.c + rthread_libc.c rthread_fork.c rthread_file.c sched_prio.c \ + rthread_cancel.c OBJS+= _atomic_lock.o rfork_thread.o cerror.o diff --git a/lib/librthread/rthread.c b/lib/librthread/rthread.c index a84043798a0..b3f059544ec 100644 --- a/lib/librthread/rthread.c +++ b/lib/librthread/rthread.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread.c,v 1.45 2011/11/09 10:28:01 guenther Exp $ */ +/* $OpenBSD: rthread.c,v 1.46 2011/12/05 04:02:03 guenther Exp $ */ /* * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org> * All Rights Reserved. @@ -98,11 +98,23 @@ _rthread_start(void *v) pthread_exit(retval); } +static void +sigthr_handler(int sig) +{ + pthread_t self = pthread_self(); + + if ((self->flags & (THREAD_CANCELED | THREAD_CANCEL_COND)) == + THREAD_CANCELED && (self->cancel_point || + (self->flags & THREAD_CANCEL_DEFERRED) == 0)) + pthread_exit(PTHREAD_CANCELED); +} + static int _rthread_init(void) { pthread_t thread = &_initial_thread; extern int __isthreaded; + struct sigaction sa; thread->tid = getthrid(); thread->donesem.lock = _SPINLOCK_UNLOCKED; @@ -129,6 +141,18 @@ _rthread_init(void) dlctl(NULL, DL_SETBINDLCK, _rthread_bind_lock); #endif + /* + * Set the handler on the signal used for cancelation and + * suspension, and make sure it's unblocked + */ + memset(&sa, 0, sizeof(sa)); + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; + sa.sa_handler = sigthr_handler; + _thread_sys_sigaction(SIGTHR, &sa, NULL); + sigaddset(&sa.sa_mask, SIGTHR); + sigprocmask(SIG_UNBLOCK, &sa.sa_mask, NULL); + return (0); } @@ -210,6 +234,16 @@ pthread_exit(void *retval) struct rthread_cleanup_fn *clfn; pthread_t thread = pthread_self(); + if (thread->flags & THREAD_DYING) { + /* + * Called pthread_exit() from destructor or cancelation + * handler: blow up. XXX write something to stderr? + */ + _exit(42); + } + + _rthread_setflag(thread, THREAD_DYING); + thread->retval = retval; for (clfn = thread->cleanup_fns; clfn; ) { @@ -379,15 +413,17 @@ int pthread_cancel(pthread_t thread) { - _rthread_setflag(thread, THREAD_CANCELLED); + _rthread_setflag(thread, THREAD_CANCELED); + if (thread->flags & THREAD_CANCEL_ENABLE) + kill(thread->tid, SIGTHR); return (0); } void pthread_testcancel(void) { - if ((pthread_self()->flags & (THREAD_CANCELLED|THREAD_CANCEL_ENABLE)) == - (THREAD_CANCELLED|THREAD_CANCEL_ENABLE)) + if ((pthread_self()->flags & (THREAD_CANCELED|THREAD_CANCEL_ENABLE)) == + (THREAD_CANCELED|THREAD_CANCEL_ENABLE)) pthread_exit(PTHREAD_CANCELED); } diff --git a/lib/librthread/rthread.h b/lib/librthread/rthread.h index adc0b28f942..66576c11b00 100644 --- a/lib/librthread/rthread.h +++ b/lib/librthread/rthread.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread.h,v 1.28 2011/11/06 12:15:51 guenther Exp $ */ +/* $OpenBSD: rthread.h,v 1.29 2011/12/05 04:02:03 guenther Exp $ */ /* * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org> * All Rights Reserved. @@ -136,12 +136,15 @@ struct pthread { struct rthread_storage *local_storage; struct rthread_cleanup_fn *cleanup_fns; int myerrno; + int cancel_point; }; #define THREAD_DONE 0x001 #define THREAD_DETACHED 0x002 -#define THREAD_CANCELLED 0x004 +#define THREAD_CANCELED 0x004 #define THREAD_CANCEL_ENABLE 0x008 #define THREAD_CANCEL_DEFERRED 0x010 +#define THREAD_CANCEL_COND 0x020 +#define THREAD_DYING 0x040 extern int _threads_ready; extern LIST_HEAD(listhead, pthread) _thread_list; @@ -167,6 +170,9 @@ void _rthread_dl_lock(int what); void _rthread_bind_lock(int); #endif +/* rthread_cancel.c */ +void _leave_cancel(pthread_t); +void _enter_cancel(pthread_t); void _thread_dump_info(void); @@ -180,3 +186,4 @@ int thrsleep(const volatile void *, clockid_t, const struct timespec *, int thrwakeup(void *, int n); int sched_yield(void); int thrsigdivert(sigset_t, siginfo_t *, const struct timespec *); +int _thread_sys_sigaction(int, const struct sigaction *, struct sigaction *); diff --git a/lib/librthread/rthread_cancel.c b/lib/librthread/rthread_cancel.c new file mode 100644 index 00000000000..9877c607fd1 --- /dev/null +++ b/lib/librthread/rthread_cancel.c @@ -0,0 +1,524 @@ +/* $OpenBSD: rthread_cancel.c,v 1.1 2011/12/05 04:02:03 guenther Exp $ */ +/* $snafu: libc_tag.c,v 1.4 2004/11/30 07:00:06 marc Exp $ */ + +/* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */ + +#define _POSIX_THREADS + +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/msg.h> +#include <sys/mman.h> +#include <sys/time.h> +#include <sys/socket.h> +#include <sys/resource.h> +#include <sys/uio.h> +#include <sys/wait.h> +#include <fcntl.h> +#include <poll.h> +#include <signal.h> +#include <stdarg.h> +#include <termios.h> +#include <unistd.h> + +#include <pthread.h> +#include <stdlib.h> +#include <string.h> + +#include "thread_private.h" /* in libc/include */ + +#include "rthread.h" + +int _thread_sys_accept(int, struct sockaddr *, socklen_t *); +int _thread_sys_close(int); +int _thread_sys_connect(int, const struct sockaddr *, socklen_t); +int _thread_sys_fcntl(int, int, ...); +int _thread_sys_fsync(int); +int _thread_sys_msgrcv(int, void *, size_t, long, int); +int _thread_sys_msgsnd(int, const void *, size_t, int); +int _thread_sys_msync(void *, size_t, int); +int _thread_sys_nanosleep(const struct timespec *, struct timespec *); +int _thread_sys_open(const char *, int, ...); +int _thread_sys_openat(int, const char *, int, ...); +int _thread_sys_poll(struct pollfd *, nfds_t, int); +ssize_t _thread_sys_pread(int, void *, size_t, off_t); +ssize_t _thread_sys_preadv(int, const struct iovec *, int, off_t); +ssize_t _thread_sys_pwrite(int, const void *, size_t, off_t); +ssize_t _thread_sys_pwritev(int, const struct iovec *, int, off_t); +ssize_t _thread_sys_read(int, void *, size_t); +ssize_t _thread_sys_readv(int, const struct iovec *, int); +ssize_t _thread_sys_recvfrom(int, void *, size_t, int, struct sockaddr *, + socklen_t *);; +ssize_t _thread_sys_recvmsg(int, struct msghdr *msg, int);; +int _thread_sys_select(int, fd_set *, fd_set *, fd_set *, + struct timeval *);; +ssize_t _thread_sys_sendmsg(int, const struct msghdr *msg, int);; +ssize_t _thread_sys_sendto(int, const void *, size_t, int, + const struct sockaddr *, socklen_t); +int _thread_sys_sigsuspend(const sigset_t *); +int _thread_sys_tcdrain(int); +pid_t _thread_sys_wait4(pid_t, int *, int, struct rusage *); +ssize_t _thread_sys_write(int, const void *, size_t); +ssize_t _thread_sys_writev(int, const struct iovec *, int); + +void +_enter_cancel(pthread_t self) +{ + if (self->flags & THREAD_CANCEL_ENABLE) { + self->cancel_point++; + if ((self->flags & (THREAD_CANCELED | THREAD_DYING)) == + THREAD_CANCELED) + pthread_exit(PTHREAD_CANCELED); + } +} + +void +_leave_cancel(pthread_t self) +{ + if (self->flags & THREAD_CANCEL_ENABLE) + self->cancel_point--; +} + + +int +accept(int fd, struct sockaddr *addr, socklen_t *addrlen) +{ + pthread_t self = pthread_self(); + int rv; + + _enter_cancel(self); + rv = _thread_sys_accept(fd, addr, addrlen); + _leave_cancel(self); + return (rv); +} + +#if 0 +aio_suspend() /* don't have yet */ +clock_nanosleep() /* don't have yet */ +#endif + +int +close(int fd) +{ + pthread_t self = pthread_self(); + int rv; + + _enter_cancel(self); + rv = _thread_sys_close(fd); + _leave_cancel(self); + return (rv); +} + +int +connect(int fd, const struct sockaddr *addr, socklen_t addrlen) +{ + pthread_t self = pthread_self(); + int rv; + + _enter_cancel(self); + rv = _thread_sys_connect(fd, addr, addrlen); + _leave_cancel(self); + return (rv); +} + +#if 0 +creat() /* built on open() */ +#endif + +int +fcntl(int fd, int cmd, ...) +{ + va_list ap; + int rv; + + va_start(ap, cmd); + switch (cmd) { + case F_DUPFD: + case F_DUPFD_CLOEXEC: + case F_SETFD: + case F_SETFL: + case F_SETOWN: + rv = _thread_sys_fcntl(fd, cmd, va_arg(ap, int)); + break; + case F_GETFD: + case F_GETFL: + case F_GETOWN: + rv = _thread_sys_fcntl(fd, cmd); + break; + case F_GETLK: + case F_SETLK: + rv = _thread_sys_fcntl(fd, cmd, va_arg(ap, struct flock *)); + break; + case F_SETLKW: + { + pthread_t self = pthread_self(); + + _enter_cancel(self); + rv = _thread_sys_fcntl(fd, cmd, va_arg(ap, struct flock *)); + _leave_cancel(self); + break; + } + default: /* should never happen? */ + rv = _thread_sys_fcntl(fd, cmd, va_arg(ap, void *)); + break; + } + va_end(ap); + return (rv); +} + +#if 0 +fdatasync() /* don't have yet */ +#endif + +int +fsync(int fd) +{ + pthread_t self = pthread_self(); + int rv; + + _enter_cancel(self); + rv = _thread_sys_fsync(fd); + _leave_cancel(self); + return (rv); +} + +#if 0 +getmsg() /* don't have: dumb STREAMS stuff */ +getpmsg() /* don't have: dumb STREAMS stuff */ +lockf() /* built on fcntl() */ +mq_receive() /* don't have yet */ +mq_send() /* don't have yet */ +mq_timedreceive() /* don't have yet */ +mq_timedsend() /* don't have yet */ +#endif + +int +msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg) +{ + pthread_t self = pthread_self(); + int rv; + + _enter_cancel(self); + rv = _thread_sys_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg); + _leave_cancel(self); + return (rv); +} + +int +msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg) +{ + pthread_t self = pthread_self(); + int rv; + + _enter_cancel(self); + rv = _thread_sys_msgsnd(msqid, msgp, msgsz, msgflg); + _leave_cancel(self); + return (rv); +} + +int +msync(void *addr, size_t len, int flags) +{ + pthread_t self = pthread_self(); + int rv; + + _enter_cancel(self); + rv = _thread_sys_msync(addr, len, flags); + _leave_cancel(self); + return (rv); +} + +int +nanosleep(const struct timespec *rqtp, struct timespec *rmtp) +{ + pthread_t self = pthread_self(); + int rv; + + _enter_cancel(self); + rv = _thread_sys_nanosleep(rqtp, rmtp); + _leave_cancel(self); + return (rv); +} + +int +open(const char *path, int flags, ...) +{ + pthread_t self = pthread_self(); + + va_list ap; + mode_t mode = 0; + int rv; + + if (flags & O_CREAT) { + va_start(ap, flags); + mode = va_arg(ap, int); + va_end(ap); + } + _enter_cancel(self); + rv = _thread_sys_open(path, flags, mode); + _leave_cancel(self); + return (rv); +} + + +int +openat(int fd, const char *path, int flags, ...) +{ + pthread_t self = pthread_self(); + + va_list ap; + mode_t mode = 0; + int rv; + + if (flags & O_CREAT) { + va_start(ap, flags); + mode = va_arg(ap, int); + va_end(ap); + } + _enter_cancel(self); + rv = _thread_sys_openat(fd, path, flags, mode); + _leave_cancel(self); + return (rv); +} + +#if 0 +pause() /* built on sigsuspend() */ +#endif + +int +poll(struct pollfd *fds, nfds_t nfds, int timeout) +{ + pthread_t self = pthread_self(); + int rv; + + _enter_cancel(self); + rv = _thread_sys_poll(fds, nfds, timeout); + _leave_cancel(self); + return (rv); +} + +ssize_t +pread(int fd, void *buf, size_t nbytes, off_t offset) +{ + pthread_t self = pthread_self(); + ssize_t rv; + + _enter_cancel(self); + rv = _thread_sys_pread(fd, buf, nbytes, offset); + _leave_cancel(self); + return (rv); +} + +ssize_t +preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset) +{ + pthread_t self = pthread_self(); + ssize_t rv; + + _enter_cancel(self); + rv = _thread_sys_preadv(fd, iov, iovcnt, offset); + _leave_cancel(self); + return (rv); +} + +#if 0 +pselect() /* don't have yet */ +putmsg() /* don't have: dumb STREAMS stuff */ +putpmsg() /* don't have: dumb STREAMS stuff */ +#endif + +ssize_t +pwrite(int fd, const void *buf, size_t nbytes, off_t offset) +{ + pthread_t self = pthread_self(); + ssize_t rv; + + _enter_cancel(self); + rv = _thread_sys_pwrite(fd, buf, nbytes, offset); + _leave_cancel(self); + return (rv); +} + +ssize_t +pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset) +{ + pthread_t self = pthread_self(); + ssize_t rv; + + _enter_cancel(self); + rv = _thread_sys_pwritev(fd, iov, iovcnt, offset); + _leave_cancel(self); + return (rv); +} + +ssize_t +read(int fd, void *buf, size_t nbytes) +{ + pthread_t self = pthread_self(); + ssize_t rv; + + _enter_cancel(self); + rv = _thread_sys_read(fd, buf, nbytes); + _leave_cancel(self); + return (rv); +} + +ssize_t +readv(int fd, const struct iovec *iov, int iovcnt) +{ + pthread_t self = pthread_self(); + ssize_t rv; + + _enter_cancel(self); + rv = _thread_sys_readv(fd, iov, iovcnt); + _leave_cancel(self); + return (rv); +} + +#if 0 +recv() /* built on recvfrom() */ +#endif + +ssize_t +recvfrom(int fd, void *buf, size_t len, int flags, struct sockaddr *addr, + socklen_t *addrlen) +{ + pthread_t self = pthread_self(); + ssize_t rv; + + _enter_cancel(self); + rv = _thread_sys_recvfrom(fd, buf, len, flags, addr, addrlen); + _leave_cancel(self); + return (rv); +} + +ssize_t +recvmsg(int fd, struct msghdr *msg, int flags) +{ + pthread_t self = pthread_self(); + ssize_t rv; + + _enter_cancel(self); + rv = _thread_sys_recvmsg(fd, msg, flags); + _leave_cancel(self); + return (rv); +} + +int +select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + struct timeval *timeout) +{ + pthread_t self = pthread_self(); + int rv; + + _enter_cancel(self); + rv = _thread_sys_select(nfds, readfds, writefds, exceptfds, timeout); + _leave_cancel(self); + return (rv); +} + +#if 0 +sem_timedwait() /* don't have yet */ +sem_wait() /* don't have yet */ +send() /* built on sendto() */ +#endif + +ssize_t +sendmsg(int fd, const struct msghdr *msg, int flags) +{ + pthread_t self = pthread_self(); + ssize_t rv; + + _enter_cancel(self); + rv = _thread_sys_sendmsg(fd, msg, flags); + _leave_cancel(self); + return (rv); +} + +ssize_t +sendto(int fd, const void *msg, size_t len, int flags, + const struct sockaddr *to, socklen_t tolen) +{ + pthread_t self = pthread_self(); + ssize_t rv; + + _enter_cancel(self); + rv = _thread_sys_sendto(fd, msg, len, flags, to, tolen); + _leave_cancel(self); + return (rv); +} + + +int +sigsuspend(const sigset_t *sigmask) +{ + pthread_t self = pthread_self(); + int rv; + + _enter_cancel(self); + rv = _thread_sys_sigsuspend(sigmask); + _leave_cancel(self); + return (rv); +} + +#if 0 +sigtimedwait() /* don't have yet */ +sigwait() /* in rthread_sig.c */ +sigwaitinfo() /* don't have yet */ +sleep() /* built on nanosleep() */ +system() /* built on wait4()? XXX */ +#endif + +int +tcdrain(int fd) +{ + pthread_t self = pthread_self(); + int rv; + + _enter_cancel(self); + rv = ioctl(fd, TIOCDRAIN, 0); + _leave_cancel(self); + return (rv); +} + +#if 0 +wait() /* built on wait4() */ +waitid() /* don't have yet */ +waitpid() /* built on wait4() */ +#endif + +pid_t +wait4(pid_t wpid, int *status, int options, struct rusage *rusage) +{ + pthread_t self = pthread_self(); + pid_t rv; + + _enter_cancel(self); + rv = _thread_sys_wait4(wpid, status, options, rusage); + _leave_cancel(self); + return (rv); +} + +ssize_t +write(int fd, const void *buf, size_t nbytes) +{ + pthread_t self = pthread_self(); + ssize_t rv; + + _enter_cancel(self); + rv = _thread_sys_write(fd, buf, nbytes); + _leave_cancel(self); + return (rv); +} + +ssize_t +writev(int fd, const struct iovec *iov, int iovcnt) +{ + pthread_t self = pthread_self(); + ssize_t rv; + + _enter_cancel(self); + rv = _thread_sys_writev(fd, iov, iovcnt); + _leave_cancel(self); + return (rv); +} diff --git a/lib/librthread/rthread_libc.c b/lib/librthread/rthread_libc.c index 3c263ba6e38..26abe3d0928 100644 --- a/lib/librthread/rthread_libc.c +++ b/lib/librthread/rthread_libc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread_libc.c,v 1.8 2011/11/06 11:48:59 guenther Exp $ */ +/* $OpenBSD: rthread_libc.c,v 1.9 2011/12/05 04:02:03 guenther Exp $ */ /* $snafu: libc_tag.c,v 1.4 2004/11/30 07:00:06 marc Exp $ */ /* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */ @@ -202,192 +202,3 @@ _thread_arc4_unlock(void) _spinunlock(&arc4_lock); } -#if 0 -/* - * miscellaneous libc exported symbols we want to override - */ -int -close(int fd) -{ - int rv; - - pthread_testcancel(); - rv = _thread_sys_close(fd); - pthread_testcancel(); - return (rv); -} - -#if 0 -/* libc calls open */ -int -creat(const char *path, mode_t mode) -{ - -} -#endif - -#if 0 -int -fcntl(int fd, int cmd, ...) -{ - va_list ap; - int rv; - - pthread_testcancel(); - va_start(ap, cmd); - rv = _thread_sys_fcntl(fd, cmd, va_arg(cmd, void *)); - va_end(ap); - pthread_testcancel(); - return (rv); -} -#endif - -int -fsync(int fd) -{ - int rv; - - pthread_testcancel(); - rv = _thread_sys_fsync(fd); - pthread_testcancel(); - return (rv); -} - -int -msync(void *addr, size_t len, int flags) -{ - int rv; - - pthread_testcancel(); - rv = _thread_sys_msync(addr, len, flags); - pthread_testcancel(); - return (rv); -} - -int -nanosleep(const struct timespec *rqtp, struct timespec *rmtp) -{ - int rv; - - pthread_testcancel(); - rv = _thread_sys_nanosleep(rqtp, rmtp); - pthread_testcancel(); - return (rv); -} - -#if 0 -int -open(const char *path, int flags, ...) -{ - - va_list ap; - int rv; - - pthread_testcancel(); - va_start(ap, cmd); - rv = _thread_sys_open(fd, cmd, va_arg(cmd, mode_t)); - va_end(ap); - pthread_testcancel(); - return (rv); -} -#endif - -#if 0 -int -pause(void) -{ - -} -#endif - -ssize_t -read(int fd, void *buf, size_t nbytes) -{ - ssize_t rv; - - pthread_testcancel(); - rv = read(fd, buf, nbytes); - pthread_testcancel(); - return (rv); -} - -#if 0 -int -sigwaitinfo() -{ - -} -#endif - -int -sigsuspend(const sigset_t *sigmask) -{ - int rv; - - pthread_testcancel(); - rv = sigsuspend(sigmask); - pthread_testcancel(); - return (rv); -} - -#if 0 -/* libc sleep(3) calls nanosleep(2), so we'll catch it there */ -unsigned int -sleep(unsigned int seconds) -{ - -} -#endif - -#if 0 -int system(const char *string) -{ - -} -#endif - -#if 0 -int -tcdrain(int fd) -{ - -} -#endif - -#if 0 -/* wait and waitpid will be handled by libc calling wait4 */ -pid_t -wait(int *status) -{ - -} - -pid_t -waitpid(pid_t wpid, int *status, int options) -{ - -} -#endif - -pid_t -wait4(pid_t wpid, int *status, int options, struct rusage *rusage) -{ - pid_t rv; - - pthread_testcancel(); - rv = _thread_sys_wait4(wpid, status, options, rusage); - pthread_testcancel(); - return (rv); -} - -ssize_t -write(int fd, const void *buf, size_t nbytes) -{ - ssize_t rv; - - pthread_testcancel(); - rv = _thread_sys_write(fd, buf, nbytes); - pthread_testcancel(); - return (rv); -} -#endif diff --git a/lib/librthread/rthread_sig.c b/lib/librthread/rthread_sig.c index cfb7b2e87c6..eea1306dc49 100644 --- a/lib/librthread/rthread_sig.c +++ b/lib/librthread/rthread_sig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread_sig.c,v 1.9 2011/11/06 11:48:59 guenther Exp $ */ +/* $OpenBSD: rthread_sig.c,v 1.10 2011/12/05 04:02:03 guenther Exp $ */ /* * Copyright (c) 2005 Ted Unangst <tedu@openbsd.org> * All Rights Reserved. @@ -35,12 +35,15 @@ pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) int sigwait(const sigset_t *set, int *sig) { + pthread_t self = pthread_self(); int ret; + _enter_cancel(self); ret = thrsigdivert(*set, NULL, NULL); + _leave_cancel(self); if (ret == -1) - return errno; + return (errno); *sig = ret; - return 0; + return (0); } |