summaryrefslogtreecommitdiff
path: root/lib/librthread
diff options
context:
space:
mode:
authorPhilip Guenthe <guenther@cvs.openbsd.org>2011-12-05 04:02:04 +0000
committerPhilip Guenthe <guenther@cvs.openbsd.org>2011-12-05 04:02:04 +0000
commit23a8eec3a155dc746eea9e0043645d95cd8b02d2 (patch)
tree331f33d030b58189df3e52e376089aa32d7a5ad6 /lib/librthread
parent42bc58bc5e3c5ed1caa935ca85099ad0c172cb06 (diff)
Implement cancelation for the basic syscall cancelation points,
using previously allocated SIGTHR to interrupt in-process syscalls and fixing the spelling of "cancelled" along the way. Modeled on FreeBSD's libthr
Diffstat (limited to 'lib/librthread')
-rw-r--r--lib/librthread/Makefile5
-rw-r--r--lib/librthread/rthread.c44
-rw-r--r--lib/librthread/rthread.h11
-rw-r--r--lib/librthread/rthread_cancel.c524
-rw-r--r--lib/librthread/rthread_libc.c191
-rw-r--r--lib/librthread/rthread_sig.c9
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);
}