Simplify sigwait code a bit by using a waitset and removing oldsigmask.
Reviewed by: deischen
This commit is contained in:
parent
9c65e7a336
commit
41282b992f
@ -544,12 +544,16 @@ enum pthread_state {
|
||||
PS_STATE_MAX
|
||||
};
|
||||
|
||||
struct sigwait_data {
|
||||
sigset_t *waitset;
|
||||
siginfo_t *siginfo; /* used to save siginfo for sigwaitinfo() */
|
||||
};
|
||||
|
||||
union pthread_wait_data {
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
struct lock *lock;
|
||||
siginfo_t *sigwaitinfo; /* used to save siginfo for sigwaitinfo() */
|
||||
struct sigwait_data *sigwait;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -663,7 +667,6 @@ struct pthread {
|
||||
* The thread's base and pending signal masks. The active
|
||||
* signal mask is stored in the thread's context (in mailbox).
|
||||
*/
|
||||
sigset_t oldsigmask;
|
||||
sigset_t sigmask;
|
||||
sigset_t sigpend;
|
||||
volatile int check_pending;
|
||||
|
@ -274,10 +274,7 @@ _thr_sig_dispatch(struct kse *curkse, int sig, siginfo_t *info)
|
||||
THR_IS_EXITING(thread) || THR_IS_SUSPENDED(thread)) {
|
||||
KSE_SCHED_UNLOCK(curkse, thread->kseg);
|
||||
_thr_ref_delete(NULL, thread);
|
||||
} else if ((thread->state == PS_SIGWAIT &&
|
||||
SIGISMEMBER(thread->oldsigmask, sig)) ||
|
||||
(thread->state != PS_SIGWAIT &&
|
||||
SIGISMEMBER(thread->sigmask, sig))) {
|
||||
} else if (SIGISMEMBER(thread->sigmask, sig)) {
|
||||
KSE_SCHED_UNLOCK(curkse, thread->kseg);
|
||||
_thr_ref_delete(NULL, thread);
|
||||
} else {
|
||||
@ -572,7 +569,7 @@ thr_sig_find(struct kse *curkse, int sig, siginfo_t *info)
|
||||
THR_IS_SUSPENDED(pthread)) {
|
||||
; /* Skip this thread. */
|
||||
} else if (pthread->state == PS_SIGWAIT &&
|
||||
!SIGISMEMBER(pthread->sigmask, sig)) {
|
||||
SIGISMEMBER(*(pthread->data.sigwait->waitset), sig)) {
|
||||
/*
|
||||
* retrieve signal from kernel, if it is job control
|
||||
* signal, and sigaction is SIG_DFL, then we will
|
||||
@ -584,8 +581,7 @@ thr_sig_find(struct kse *curkse, int sig, siginfo_t *info)
|
||||
DBG_MSG("Waking thread %p in sigwait"
|
||||
" with signal %d\n", pthread, sig);
|
||||
/* where to put siginfo ? */
|
||||
*(pthread->data.sigwaitinfo) = si;
|
||||
pthread->sigmask = pthread->oldsigmask;
|
||||
*(pthread->data.sigwait->siginfo) = si;
|
||||
kmbx = _thr_setrunnable_unlocked(pthread);
|
||||
}
|
||||
KSE_SCHED_UNLOCK(curkse, pthread->kseg);
|
||||
@ -603,9 +599,7 @@ thr_sig_find(struct kse *curkse, int sig, siginfo_t *info)
|
||||
if (kmbx != NULL)
|
||||
kse_wakeup(kmbx);
|
||||
return (NULL);
|
||||
} else if (!SIGISMEMBER(pthread->sigmask, sig) ||
|
||||
(!SIGISMEMBER(pthread->oldsigmask, sig) &&
|
||||
pthread->state == PS_SIGWAIT)) {
|
||||
} else if (!SIGISMEMBER(pthread->sigmask, sig)) {
|
||||
sigfunc = _thread_sigact[sig - 1].sa_sigaction;
|
||||
if ((__sighandler_t *)sigfunc == SIG_DFL) {
|
||||
if (sigprop(sig) & SA_KILL) {
|
||||
@ -939,19 +933,17 @@ _thr_sig_add(struct pthread *pthread, int sig, siginfo_t *info)
|
||||
*/
|
||||
suppress_handler = 1;
|
||||
/* Wake up the thread if the signal is not blocked. */
|
||||
if (!SIGISMEMBER(pthread->sigmask, sig)) {
|
||||
if (SIGISMEMBER(*(pthread->data.sigwait->waitset), sig)) {
|
||||
/* Return the signal number: */
|
||||
*(pthread->data.sigwaitinfo) = pthread->siginfo[sig-1];
|
||||
pthread->sigmask = pthread->oldsigmask;
|
||||
*(pthread->data.sigwait->siginfo) = pthread->siginfo[sig-1];
|
||||
/* Make the thread runnable: */
|
||||
kmbx = _thr_setrunnable_unlocked(pthread);
|
||||
} else {
|
||||
/* Increment the pending signal count. */
|
||||
SIGADDSET(pthread->sigpend, sig);
|
||||
if (!SIGISMEMBER(pthread->oldsigmask, sig)) {
|
||||
if (!SIGISMEMBER(pthread->sigmask, sig)) {
|
||||
pthread->check_pending = 1;
|
||||
pthread->interrupted = 1;
|
||||
pthread->sigmask = pthread->oldsigmask;
|
||||
kmbx = _thr_setrunnable_unlocked(pthread);
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ lib_sigtimedwait(const sigset_t *set, siginfo_t *info,
|
||||
struct pthread *curthread = _get_curthread();
|
||||
int ret = 0;
|
||||
int i;
|
||||
struct sigwait_data waitdata;
|
||||
sigset_t waitset;
|
||||
kse_critical_t crit;
|
||||
siginfo_t siginfo;
|
||||
@ -97,11 +98,10 @@ lib_sigtimedwait(const sigset_t *set, siginfo_t *info,
|
||||
curthread->interrupted = 0;
|
||||
_thr_set_timeout(timeout);
|
||||
/* Wait for a signal: */
|
||||
curthread->oldsigmask = curthread->sigmask;
|
||||
siginfo.si_signo = 0;
|
||||
curthread->data.sigwaitinfo = &siginfo;
|
||||
SIGFILLSET(curthread->sigmask);
|
||||
SIGSETNAND(curthread->sigmask, waitset);
|
||||
waitdata.waitset = &waitset;
|
||||
waitdata.siginfo = &siginfo;
|
||||
curthread->data.sigwait = &waitdata;
|
||||
THR_SET_STATE(curthread, PS_SIGWAIT);
|
||||
_thr_sched_switch_unlocked(curthread);
|
||||
/*
|
||||
@ -122,7 +122,7 @@ lib_sigtimedwait(const sigset_t *set, siginfo_t *info,
|
||||
* Probably unnecessary, but since it's in a union struct
|
||||
* we don't know how it could be used in the future.
|
||||
*/
|
||||
curthread->data.sigwaitinfo = NULL;
|
||||
curthread->data.sigwait = NULL;
|
||||
|
||||
OUT:
|
||||
if (ret > 0 && info != NULL)
|
||||
|
@ -544,12 +544,16 @@ enum pthread_state {
|
||||
PS_STATE_MAX
|
||||
};
|
||||
|
||||
struct sigwait_data {
|
||||
sigset_t *waitset;
|
||||
siginfo_t *siginfo; /* used to save siginfo for sigwaitinfo() */
|
||||
};
|
||||
|
||||
union pthread_wait_data {
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
struct lock *lock;
|
||||
siginfo_t *sigwaitinfo; /* used to save siginfo for sigwaitinfo() */
|
||||
struct sigwait_data *sigwait;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -663,7 +667,6 @@ struct pthread {
|
||||
* The thread's base and pending signal masks. The active
|
||||
* signal mask is stored in the thread's context (in mailbox).
|
||||
*/
|
||||
sigset_t oldsigmask;
|
||||
sigset_t sigmask;
|
||||
sigset_t sigpend;
|
||||
volatile int check_pending;
|
||||
|
@ -274,10 +274,7 @@ _thr_sig_dispatch(struct kse *curkse, int sig, siginfo_t *info)
|
||||
THR_IS_EXITING(thread) || THR_IS_SUSPENDED(thread)) {
|
||||
KSE_SCHED_UNLOCK(curkse, thread->kseg);
|
||||
_thr_ref_delete(NULL, thread);
|
||||
} else if ((thread->state == PS_SIGWAIT &&
|
||||
SIGISMEMBER(thread->oldsigmask, sig)) ||
|
||||
(thread->state != PS_SIGWAIT &&
|
||||
SIGISMEMBER(thread->sigmask, sig))) {
|
||||
} else if (SIGISMEMBER(thread->sigmask, sig)) {
|
||||
KSE_SCHED_UNLOCK(curkse, thread->kseg);
|
||||
_thr_ref_delete(NULL, thread);
|
||||
} else {
|
||||
@ -572,7 +569,7 @@ thr_sig_find(struct kse *curkse, int sig, siginfo_t *info)
|
||||
THR_IS_SUSPENDED(pthread)) {
|
||||
; /* Skip this thread. */
|
||||
} else if (pthread->state == PS_SIGWAIT &&
|
||||
!SIGISMEMBER(pthread->sigmask, sig)) {
|
||||
SIGISMEMBER(*(pthread->data.sigwait->waitset), sig)) {
|
||||
/*
|
||||
* retrieve signal from kernel, if it is job control
|
||||
* signal, and sigaction is SIG_DFL, then we will
|
||||
@ -584,8 +581,7 @@ thr_sig_find(struct kse *curkse, int sig, siginfo_t *info)
|
||||
DBG_MSG("Waking thread %p in sigwait"
|
||||
" with signal %d\n", pthread, sig);
|
||||
/* where to put siginfo ? */
|
||||
*(pthread->data.sigwaitinfo) = si;
|
||||
pthread->sigmask = pthread->oldsigmask;
|
||||
*(pthread->data.sigwait->siginfo) = si;
|
||||
kmbx = _thr_setrunnable_unlocked(pthread);
|
||||
}
|
||||
KSE_SCHED_UNLOCK(curkse, pthread->kseg);
|
||||
@ -603,9 +599,7 @@ thr_sig_find(struct kse *curkse, int sig, siginfo_t *info)
|
||||
if (kmbx != NULL)
|
||||
kse_wakeup(kmbx);
|
||||
return (NULL);
|
||||
} else if (!SIGISMEMBER(pthread->sigmask, sig) ||
|
||||
(!SIGISMEMBER(pthread->oldsigmask, sig) &&
|
||||
pthread->state == PS_SIGWAIT)) {
|
||||
} else if (!SIGISMEMBER(pthread->sigmask, sig)) {
|
||||
sigfunc = _thread_sigact[sig - 1].sa_sigaction;
|
||||
if ((__sighandler_t *)sigfunc == SIG_DFL) {
|
||||
if (sigprop(sig) & SA_KILL) {
|
||||
@ -939,19 +933,17 @@ _thr_sig_add(struct pthread *pthread, int sig, siginfo_t *info)
|
||||
*/
|
||||
suppress_handler = 1;
|
||||
/* Wake up the thread if the signal is not blocked. */
|
||||
if (!SIGISMEMBER(pthread->sigmask, sig)) {
|
||||
if (SIGISMEMBER(*(pthread->data.sigwait->waitset), sig)) {
|
||||
/* Return the signal number: */
|
||||
*(pthread->data.sigwaitinfo) = pthread->siginfo[sig-1];
|
||||
pthread->sigmask = pthread->oldsigmask;
|
||||
*(pthread->data.sigwait->siginfo) = pthread->siginfo[sig-1];
|
||||
/* Make the thread runnable: */
|
||||
kmbx = _thr_setrunnable_unlocked(pthread);
|
||||
} else {
|
||||
/* Increment the pending signal count. */
|
||||
SIGADDSET(pthread->sigpend, sig);
|
||||
if (!SIGISMEMBER(pthread->oldsigmask, sig)) {
|
||||
if (!SIGISMEMBER(pthread->sigmask, sig)) {
|
||||
pthread->check_pending = 1;
|
||||
pthread->interrupted = 1;
|
||||
pthread->sigmask = pthread->oldsigmask;
|
||||
kmbx = _thr_setrunnable_unlocked(pthread);
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ lib_sigtimedwait(const sigset_t *set, siginfo_t *info,
|
||||
struct pthread *curthread = _get_curthread();
|
||||
int ret = 0;
|
||||
int i;
|
||||
struct sigwait_data waitdata;
|
||||
sigset_t waitset;
|
||||
kse_critical_t crit;
|
||||
siginfo_t siginfo;
|
||||
@ -97,11 +98,10 @@ lib_sigtimedwait(const sigset_t *set, siginfo_t *info,
|
||||
curthread->interrupted = 0;
|
||||
_thr_set_timeout(timeout);
|
||||
/* Wait for a signal: */
|
||||
curthread->oldsigmask = curthread->sigmask;
|
||||
siginfo.si_signo = 0;
|
||||
curthread->data.sigwaitinfo = &siginfo;
|
||||
SIGFILLSET(curthread->sigmask);
|
||||
SIGSETNAND(curthread->sigmask, waitset);
|
||||
waitdata.waitset = &waitset;
|
||||
waitdata.siginfo = &siginfo;
|
||||
curthread->data.sigwait = &waitdata;
|
||||
THR_SET_STATE(curthread, PS_SIGWAIT);
|
||||
_thr_sched_switch_unlocked(curthread);
|
||||
/*
|
||||
@ -122,7 +122,7 @@ lib_sigtimedwait(const sigset_t *set, siginfo_t *info,
|
||||
* Probably unnecessary, but since it's in a union struct
|
||||
* we don't know how it could be used in the future.
|
||||
*/
|
||||
curthread->data.sigwaitinfo = NULL;
|
||||
curthread->data.sigwait = NULL;
|
||||
|
||||
OUT:
|
||||
if (ret > 0 && info != NULL)
|
||||
|
Loading…
Reference in New Issue
Block a user