mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2025-10-19 20:43:43 +08:00
[smart] Fix bugs on lwp kill (#7892)
Signed-off-by: Shell <smokewood@qq.com>
This commit is contained in:
@@ -546,32 +546,36 @@ void lwp_thread_signal_catch(void *exp_frame)
|
||||
* @note that the p_usi is release before entering signal action by
|
||||
* reseting the kernel sp.
|
||||
*/
|
||||
LOG_D("%s: enter signal handler(signo=%d) at %p", __func__, signo, handler);
|
||||
arch_thread_signal_enter(signo, p_usi, exp_frame, handler, &save_sig_mask);
|
||||
/* the arch_thread_signal_enter() never return */
|
||||
RT_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
static int _do_signal_wakeup(rt_thread_t thread, int sig)
|
||||
{
|
||||
int need_schedule;
|
||||
if ((thread->stat & RT_THREAD_SUSPEND_MASK) == RT_THREAD_SUSPEND_MASK)
|
||||
if (!_sigismember(&thread->signal.sigset_mask, sig))
|
||||
{
|
||||
|
||||
if ((thread->stat & RT_SIGNAL_COMMON_WAKEUP_MASK) != RT_SIGNAL_COMMON_WAKEUP_MASK)
|
||||
if ((thread->stat & RT_THREAD_SUSPEND_MASK) == RT_THREAD_SUSPEND_MASK)
|
||||
{
|
||||
rt_thread_wakeup(thread);
|
||||
need_schedule = 1;
|
||||
}
|
||||
else if ((sig == SIGKILL) && ((thread->stat & RT_SIGNAL_KILL_WAKEUP_MASK) != RT_SIGNAL_KILL_WAKEUP_MASK))
|
||||
{
|
||||
rt_thread_wakeup(thread);
|
||||
need_schedule = 1;
|
||||
if ((thread->stat & RT_SIGNAL_COMMON_WAKEUP_MASK) != RT_SIGNAL_COMMON_WAKEUP_MASK)
|
||||
{
|
||||
rt_thread_wakeup(thread);
|
||||
need_schedule = 1;
|
||||
}
|
||||
else if ((sig == SIGKILL) && ((thread->stat & RT_SIGNAL_KILL_WAKEUP_MASK) != RT_SIGNAL_KILL_WAKEUP_MASK))
|
||||
{
|
||||
rt_thread_wakeup(thread);
|
||||
need_schedule = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
need_schedule = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
need_schedule = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
need_schedule = 0;
|
||||
@@ -633,7 +637,7 @@ static int _siginfo_deliver_to_lwp(struct rt_lwp *lwp, lwp_siginfo_t siginfo)
|
||||
return _do_signal_wakeup(catcher, siginfo->ksiginfo.signo);
|
||||
}
|
||||
|
||||
static int _siginfo_deliver_to_thread(struct rt_lwp *lwp, rt_thread_t thread, lwp_siginfo_t siginfo)
|
||||
static int _siginfo_deliver_to_thread(rt_thread_t thread, lwp_siginfo_t siginfo)
|
||||
{
|
||||
sigqueue_enqueue(_SIGQ(thread), siginfo);
|
||||
return _do_signal_wakeup(thread, siginfo->ksiginfo.signo);
|
||||
@@ -679,6 +683,9 @@ rt_err_t lwp_signal_kill(struct rt_lwp *lwp, long signo, long code, long value)
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_D("%s(lwp=%p \"%s\",signo=%ld,code=%ld,value=%ld)",
|
||||
__func__, lwp, lwp->cmd, signo, code, value);
|
||||
|
||||
need_schedule = RT_FALSE;
|
||||
|
||||
/* FIXME: acquire READ lock to lwp */
|
||||
@@ -848,7 +855,7 @@ rt_err_t lwp_thread_signal_kill(rt_thread_t thread, long signo, long code, long
|
||||
|
||||
if (siginfo)
|
||||
{
|
||||
need_schedule = _siginfo_deliver_to_thread(lwp, thread, siginfo);
|
||||
need_schedule = _siginfo_deliver_to_thread(thread, siginfo);
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
@@ -943,10 +950,10 @@ static int _dequeue_signal(rt_thread_t thread, lwp_sigset_t *mask, siginfo_t *us
|
||||
rt_err_t lwp_thread_signal_timedwait(rt_thread_t thread, lwp_sigset_t *sigset,
|
||||
siginfo_t *usi, struct timespec *timeout)
|
||||
{
|
||||
LOG_D("%s", __func__);
|
||||
|
||||
rt_base_t level;
|
||||
rt_err_t ret;
|
||||
lwp_sigset_t saved_sigset;
|
||||
lwp_sigset_t blocked_sigset;
|
||||
int sig;
|
||||
|
||||
/**
|
||||
@@ -960,6 +967,7 @@ rt_err_t lwp_thread_signal_timedwait(rt_thread_t thread, lwp_sigset_t *sigset,
|
||||
_sigdelset(sigset, SIGSTOP);
|
||||
_signotsets(sigset, sigset);
|
||||
|
||||
|
||||
/* FIXME: acquire READ lock to lwp */
|
||||
level = rt_hw_interrupt_disable();
|
||||
sig = _dequeue_signal(thread, sigset, usi);
|
||||
@@ -967,17 +975,19 @@ rt_err_t lwp_thread_signal_timedwait(rt_thread_t thread, lwp_sigset_t *sigset,
|
||||
if (sig)
|
||||
return sig;
|
||||
|
||||
/* WARNING atomic problem, what if pending signal arrives before we sleep */
|
||||
|
||||
/**
|
||||
* @brief POSIX
|
||||
* if none of the signals specified by set are pending, sigtimedwait() shall
|
||||
* wait for the time interval specified in the timespec structure referenced
|
||||
* by timeout.
|
||||
*
|
||||
* @note If the pending signal arrives before thread suspend, the suspend
|
||||
* operation will return a failure
|
||||
*/
|
||||
_sigandsets(&blocked_sigset, &thread->signal.sigset_mask, sigset);
|
||||
_thread_signal_mask(thread, LWP_SIG_MASK_CMD_SET_MASK, &blocked_sigset, &saved_sigset);
|
||||
if (timeout)
|
||||
{
|
||||
/* TODO: verify timeout valid ? not overflow 32bits, nanosec valid, ... */
|
||||
rt_uint32_t time;
|
||||
time = rt_timespec_to_tick(timeout);
|
||||
|
||||
@@ -1006,9 +1016,14 @@ rt_err_t lwp_thread_signal_timedwait(rt_thread_t thread, lwp_sigset_t *sigset,
|
||||
if (ret == RT_EOK)
|
||||
{
|
||||
rt_schedule();
|
||||
ret = -EAGAIN;
|
||||
/* If thread->error reliable? */
|
||||
if (thread->error == -RT_EINTR)
|
||||
ret = -EINTR;
|
||||
else
|
||||
ret = -EAGAIN;
|
||||
}
|
||||
/* else ret == -EINTR */
|
||||
_thread_signal_mask(thread, LWP_SIG_MASK_CMD_SET_MASK, &saved_sigset, RT_NULL);
|
||||
|
||||
/* FIXME: acquire READ lock to lwp */
|
||||
level = rt_hw_interrupt_disable();
|
||||
|
Reference in New Issue
Block a user