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.
This commit is contained in:
parent
1d7baed662
commit
5193e44c40
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user