From 5193e44c401f0c7a1515d53af97010ad4ec2a5b8 Mon Sep 17 00:00:00 2001 From: davidxu Date: Tue, 25 Jul 2006 12:50:05 +0000 Subject: [PATCH] 1. Don't override underscore version of aio_suspend(), system(), wait(), waitpid() and usleep(), they are internal versions and should not be cancellation points. 2. Make wait3() as a cancellation point. 3. Move raise() and pause() into file thr_sig.c. 4. Add functions _sigsuspend, _sigwait, _sigtimedwait and _sigwaitinfo, remove SIGCANCEL bit in wait-set for those functions, the signal is used internally to implement thread cancellation. --- lib/libthr/pthread.map | 44 ++++++------- lib/libthr/thread/thr_init.c | 34 +++++----- lib/libthr/thread/thr_sig.c | 108 ++++++++++++++++++++++++++++++- lib/libthr/thread/thr_syscalls.c | 107 +++++++++++++----------------- 4 files changed, 192 insertions(+), 101 deletions(-) diff --git a/lib/libthr/pthread.map b/lib/libthr/pthread.map index 66ebf4471b2f..1d6f50867e40 100644 --- a/lib/libthr/pthread.map +++ b/lib/libthr/pthread.map @@ -2,7 +2,16 @@ LIBTHREAD_1_0 { global: ___creat; + ___pause; + ___pselect; + ___sleep; + ___system; + ___tcdrain; + ___usleep; + ___wait; + ___waitpid; __accept; + __aio_suspend; __close; __connect; __error; @@ -29,15 +38,11 @@ global: __sigtimedwait; __sigwait; __sigwaitinfo; + __wait3; __wait4; __write; __writev; - _aio_suspend; - _execve; _fork; - _nanosleep; - _pause; - _pselect; _pthread_atfork; _pthread_barrier_destroy; _pthread_barrier_init; @@ -169,16 +174,10 @@ global: _sigtimedwait; _sigwait; _sigwaitinfo; - _sleep; _spinlock; _spinlock_debug; _spinunlock; - _system; - _tcdrain; - _usleep; _vfork; - _wait; - _waitpid; accept; aio_suspend; close; @@ -338,6 +337,7 @@ global: usleep; vfork; wait; + wait3; wait4; waitpid; write; @@ -538,6 +538,7 @@ global: usleep; vfork; wait; + wait3; wait4; waitpid; write; @@ -553,7 +554,16 @@ local: FBSDprivate { global: ___creat; + ___pause; + ___pselect; + ___sleep; + ___system; + ___tcdrain; + ___usleep; + ___wait; + ___waitpid; __accept; + __aio_suspend; __close; __connect; __fcntl; @@ -579,15 +589,11 @@ global: __sigtimedwait; __sigwait; __sigwaitinfo; + __wait3; __wait4; __write; __writev; - _aio_suspend; - _execve; _fork; - _nanosleep; - _pause; - _pselect; _pthread_atfork; _pthread_barrier_destroy; _pthread_barrier_init; @@ -719,16 +725,10 @@ global: _sigtimedwait; _sigwait; _sigwaitinfo; - _sleep; _spinlock; _spinlock_debug; _spinunlock; - _system; - _tcdrain; - _usleep; _vfork; - _wait; - _waitpid; # Debugger needs these. _libthr_debug; diff --git a/lib/libthr/thread/thr_init.c b/lib/libthr/thread/thr_init.c index 490c1b7dcaf5..1150985ed071 100644 --- a/lib/libthr/thread/thr_init.c +++ b/lib/libthr/thread/thr_init.c @@ -123,13 +123,8 @@ static void init_main_thread(struct pthread *thread); * All weak references used within libc should be in this table. * This is so that static libraries will work. */ -STATIC_LIB_REQUIRE(_accept); -STATIC_LIB_REQUIRE(_close); -STATIC_LIB_REQUIRE(_connect); -STATIC_LIB_REQUIRE(_fcntl); -STATIC_LIB_REQUIRE(_fsync); -STATIC_LIB_REQUIRE(_nanosleep); -STATIC_LIB_REQUIRE(_open); + +STATIC_LIB_REQUIRE(_fork); STATIC_LIB_REQUIRE(_pthread_getspecific); STATIC_LIB_REQUIRE(_pthread_key_create); STATIC_LIB_REQUIRE(_pthread_key_delete); @@ -143,20 +138,25 @@ STATIC_LIB_REQUIRE(_pthread_mutexattr_destroy); STATIC_LIB_REQUIRE(_pthread_mutexattr_settype); STATIC_LIB_REQUIRE(_pthread_once); STATIC_LIB_REQUIRE(_pthread_setspecific); -STATIC_LIB_REQUIRE(_read); -STATIC_LIB_REQUIRE(_readv); -STATIC_LIB_REQUIRE(_recvfrom); -STATIC_LIB_REQUIRE(_recvmsg); -STATIC_LIB_REQUIRE(_select); -STATIC_LIB_REQUIRE(_sendmsg); -STATIC_LIB_REQUIRE(_sendto); +STATIC_LIB_REQUIRE(_raise); +STATIC_LIB_REQUIRE(_sem_destroy); +STATIC_LIB_REQUIRE(_sem_getvalue); +STATIC_LIB_REQUIRE(_sem_init); +STATIC_LIB_REQUIRE(_sem_post); +STATIC_LIB_REQUIRE(_sem_timedwait); +STATIC_LIB_REQUIRE(_sem_trywait); +STATIC_LIB_REQUIRE(_sem_wait); STATIC_LIB_REQUIRE(_sigaction); STATIC_LIB_REQUIRE(_sigprocmask); STATIC_LIB_REQUIRE(_sigsuspend); +STATIC_LIB_REQUIRE(_sigtimedwait); +STATIC_LIB_REQUIRE(_sigwait); +STATIC_LIB_REQUIRE(_sigwaitinfo); +STATIC_LIB_REQUIRE(_spinlock); +STATIC_LIB_REQUIRE(_spinlock_debug); +STATIC_LIB_REQUIRE(_spinunlock); STATIC_LIB_REQUIRE(_thread_init_hack); -STATIC_LIB_REQUIRE(_wait4); -STATIC_LIB_REQUIRE(_write); -STATIC_LIB_REQUIRE(_writev); +STATIC_LIB_REQUIRE(_vfork); /* * These are needed when linking statically. All references within diff --git a/lib/libthr/thread/thr_sig.c b/lib/libthr/thread/thr_sig.c index 865fb72f7d55..0cd9afc7a222 100644 --- a/lib/libthr/thread/thr_sig.c +++ b/lib/libthr/thread/thr_sig.c @@ -47,6 +47,9 @@ #define DBG_MSG(x...) #endif +extern int __pause(void); +int ___pause(void); +int _raise(int); int __sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec * timeout); int __sigwaitinfo(const sigset_t *set, siginfo_t *info); @@ -145,6 +148,36 @@ _thr_signal_deinit(void) { } +__weak_reference(___pause, pause); + +int +___pause(void) +{ + struct pthread *curthread = _get_curthread(); + int oldcancel; + int ret; + + oldcancel = _thr_cancel_enter(curthread); + ret = __pause(); + _thr_cancel_leave(curthread, oldcancel); + + return ret; +} + +__weak_reference(_raise, raise); + +int +_raise(int sig) +{ + int ret; + + if (!_thr_isthreaded()) + ret = kill(getpid(), sig); + else + ret = _thr_send_sig(_get_curthread(), sig); + return (ret); +} + __weak_reference(_sigaction, sigaction); int @@ -188,10 +221,29 @@ _pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) return (0); } -__weak_reference(_sigsuspend, sigsuspend); +__weak_reference(__sigsuspend, sigsuspend); int _sigsuspend(const sigset_t * set) +{ + sigset_t newset; + const sigset_t *pset; + int ret; + + if (SIGISMEMBER(*set, SIGCANCEL)) { + newset = *set; + SIGDELSET(newset, SIGCANCEL); + pset = &newset; + } else + pset = set; + + ret = __sys_sigsuspend(pset); + + return (ret); +} + +int +__sigsuspend(const sigset_t * set) { struct pthread *curthread = _get_curthread(); sigset_t newset; @@ -217,6 +269,24 @@ __weak_reference(__sigwait, sigwait); __weak_reference(__sigtimedwait, sigtimedwait); __weak_reference(__sigwaitinfo, sigwaitinfo); +int +_sigtimedwait(const sigset_t *set, siginfo_t *info, + const struct timespec * timeout) +{ + sigset_t newset; + const sigset_t *pset; + int ret; + + if (SIGISMEMBER(*set, SIGCANCEL)) { + newset = *set; + SIGDELSET(newset, SIGCANCEL); + pset = &newset; + } else + pset = set; + ret = __sys_sigtimedwait(pset, info, timeout); + return (ret); +} + int __sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec * timeout) @@ -239,6 +309,24 @@ __sigtimedwait(const sigset_t *set, siginfo_t *info, return (ret); } +int +_sigwaitinfo(const sigset_t *set, siginfo_t *info) +{ + sigset_t newset; + const sigset_t *pset; + int ret; + + if (SIGISMEMBER(*set, SIGCANCEL)) { + newset = *set; + SIGDELSET(newset, SIGCANCEL); + pset = &newset; + } else + pset = set; + + ret = __sys_sigwaitinfo(pset, info); + return (ret); +} + int __sigwaitinfo(const sigset_t *set, siginfo_t *info) { @@ -261,6 +349,24 @@ __sigwaitinfo(const sigset_t *set, siginfo_t *info) return (ret); } +int +_sigwait(const sigset_t *set, int *sig) +{ + sigset_t newset; + const sigset_t *pset; + int ret; + + if (SIGISMEMBER(*set, SIGCANCEL)) { + newset = *set; + SIGDELSET(newset, SIGCANCEL); + pset = &newset; + } else + pset = set; + + ret = __sys_sigwait(pset, sig); + return (ret); +} + int __sigwait(const sigset_t *set, int *sig) { diff --git a/lib/libthr/thread/thr_syscalls.c b/lib/libthr/thread/thr_syscalls.c index a36849a417f1..f994288610ad 100644 --- a/lib/libthr/thread/thr_syscalls.c +++ b/lib/libthr/thread/thr_syscalls.c @@ -93,7 +93,6 @@ #include "thr_private.h" extern int __creat(const char *, mode_t); -extern int __pause(void); extern int __pselect(int, fd_set *, fd_set *, fd_set *, const struct timespec *, const sigset_t *); extern unsigned __sleep(unsigned int); @@ -122,7 +121,17 @@ extern pid_t __sys_wait4(pid_t, int *, int, struct rusage *); extern ssize_t __sys_writev(int, const struct iovec *, int); int ___creat(const char *, mode_t); +int ___pselect(int, fd_set *, fd_set *, fd_set *, + const struct timespec *, const sigset_t *); +unsigned ___sleep(unsigned); +int ___system(const char *); +int ___tcdrain(int); +int ___usleep(useconds_t useconds); +pid_t ___wait(int *); +pid_t ___waitpid(pid_t, int *, int); int __accept(int, struct sockaddr *, socklen_t *); +int __aio_suspend(const struct aiocb * const iocbs[], int, + const struct timespec *); int __close(int); int __connect(int, const struct sockaddr *, socklen_t); int __fcntl(int, int,...); @@ -139,21 +148,11 @@ int __select(int, fd_set *, fd_set *, fd_set *, struct timeval *); ssize_t __sendmsg(int, const struct msghdr *, int); ssize_t __sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t); +pid_t __wait3(int *, int, struct rusage *); pid_t __wait4(pid_t, int *, int, struct rusage *); ssize_t __write(int, const void *, size_t); ssize_t __writev(int, const struct iovec *, int); -int _aio_suspend(const struct aiocb * const iocbs[], int, - const struct timespec *); -int _pause(void); -int _pselect(int, fd_set *, fd_set *, fd_set *, - const struct timespec *, const sigset_t *); -int _raise(int); -unsigned _sleep(unsigned); -int _system(const char *); -int _tcdrain(int); int _vfork(void); -pid_t _wait(int *); - __weak_reference(__accept, accept); @@ -172,10 +171,10 @@ __accept(int s, struct sockaddr *addr, socklen_t *addrlen) return (ret); } -__weak_reference(_aio_suspend, aio_suspend); +__weak_reference(__aio_suspend, aio_suspend); int -_aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct +__aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct timespec *timeout) { struct pthread *curthread = _get_curthread(); @@ -349,22 +348,6 @@ __open(const char *path, int flags,...) return ret; } -__weak_reference(_pause, pause); - -int -_pause(void) -{ - struct pthread *curthread = _get_curthread(); - int oldcancel; - int ret; - - oldcancel = _thr_cancel_enter(curthread); - ret = __pause(); - _thr_cancel_leave(curthread, oldcancel); - - return ret; -} - __weak_reference(__poll, poll); int @@ -381,10 +364,10 @@ __poll(struct pollfd *fds, unsigned int nfds, int timeout) return ret; } -__weak_reference(_pselect, pselect); +__weak_reference(___pselect, pselect); int -_pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds, +___pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds, const struct timespec *timo, const sigset_t *mask) { struct pthread *curthread = _get_curthread(); @@ -398,20 +381,6 @@ _pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds, return (ret); } -__weak_reference(_raise, raise); - -int -_raise(int sig) -{ - int ret; - - if (!_thr_isthreaded()) - ret = kill(getpid(), sig); - else - ret = _thr_send_sig(_get_curthread(), sig); - return (ret); -} - __weak_reference(__read, read); ssize_t @@ -522,10 +491,10 @@ __sendto(int s, const void *m, size_t l, int f, const struct sockaddr *t, return (ret); } -__weak_reference(_sleep, sleep); +__weak_reference(___sleep, sleep); unsigned int -_sleep(unsigned int seconds) +___sleep(unsigned int seconds) { struct pthread *curthread = _get_curthread(); int oldcancel; @@ -538,10 +507,10 @@ _sleep(unsigned int seconds) return (ret); } -__weak_reference(_system, system); +__weak_reference(___system, system); int -_system(const char *string) +___system(const char *string) { struct pthread *curthread = _get_curthread(); int oldcancel; @@ -554,10 +523,10 @@ _system(const char *string) return ret; } -__weak_reference(_tcdrain, tcdrain); +__weak_reference(___tcdrain, tcdrain); int -_tcdrain(int fd) +___tcdrain(int fd) { struct pthread *curthread = _get_curthread(); int oldcancel; @@ -570,10 +539,10 @@ _tcdrain(int fd) return (ret); } -__weak_reference(_usleep, usleep); +__weak_reference(___usleep, usleep); int -_usleep(useconds_t useconds) +___usleep(useconds_t useconds) { struct pthread *curthread = _get_curthread(); int oldcancel; @@ -594,10 +563,10 @@ _vfork(void) return (fork()); } -__weak_reference(_wait, wait); +__weak_reference(___wait, wait); pid_t -_wait(int *istat) +___wait(int *istat) { struct pthread *curthread = _get_curthread(); int oldcancel; @@ -610,26 +579,42 @@ _wait(int *istat) return ret; } -__weak_reference(__wait4, wait4); +__weak_reference(__wait3, wait3); pid_t -__wait4(pid_t pid, int *istat, int options, struct rusage *rusage) +__wait3(int *status, int options, struct rusage *rusage) { struct pthread *curthread = _get_curthread(); int oldcancel; pid_t ret; oldcancel = _thr_cancel_enter(curthread); - ret = __sys_wait4(pid, istat, options, rusage); + ret = _wait4(WAIT_ANY, status, options, rusage); + _thr_cancel_leave(curthread, oldcancel); + + return (ret); +} + +__weak_reference(__wait4, wait4); + +pid_t +__wait4(pid_t pid, int *status, int options, struct rusage *rusage) +{ + struct pthread *curthread = _get_curthread(); + int oldcancel; + pid_t ret; + + oldcancel = _thr_cancel_enter(curthread); + ret = __sys_wait4(pid, status, options, rusage); _thr_cancel_leave(curthread, oldcancel); return ret; } -__weak_reference(_waitpid, waitpid); +__weak_reference(___waitpid, waitpid); pid_t -_waitpid(pid_t wpid, int *status, int options) +___waitpid(pid_t wpid, int *status, int options) { struct pthread *curthread = _get_curthread(); int oldcancel;