|
@@ -546,32 +546,36 @@ void lwp_thread_signal_catch(void *exp_frame)
|
|
* @note that the p_usi is release before entering signal action by
|
|
* @note that the p_usi is release before entering signal action by
|
|
* reseting the kernel sp.
|
|
* 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);
|
|
arch_thread_signal_enter(signo, p_usi, exp_frame, handler, &save_sig_mask);
|
|
/* the arch_thread_signal_enter() never return */
|
|
/* the arch_thread_signal_enter() never return */
|
|
RT_ASSERT(0);
|
|
RT_ASSERT(0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
static int _do_signal_wakeup(rt_thread_t thread, int sig)
|
|
static int _do_signal_wakeup(rt_thread_t thread, int sig)
|
|
{
|
|
{
|
|
int need_schedule;
|
|
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
|
|
else
|
|
- {
|
|
|
|
need_schedule = 0;
|
|
need_schedule = 0;
|
|
- }
|
|
|
|
}
|
|
}
|
|
else
|
|
else
|
|
need_schedule = 0;
|
|
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);
|
|
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);
|
|
sigqueue_enqueue(_SIGQ(thread), siginfo);
|
|
return _do_signal_wakeup(thread, siginfo->ksiginfo.signo);
|
|
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
|
|
else
|
|
{
|
|
{
|
|
|
|
+ LOG_D("%s(lwp=%p \"%s\",signo=%ld,code=%ld,value=%ld)",
|
|
|
|
+ __func__, lwp, lwp->cmd, signo, code, value);
|
|
|
|
+
|
|
need_schedule = RT_FALSE;
|
|
need_schedule = RT_FALSE;
|
|
|
|
|
|
/* FIXME: acquire READ lock to lwp */
|
|
/* 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)
|
|
if (siginfo)
|
|
{
|
|
{
|
|
- need_schedule = _siginfo_deliver_to_thread(lwp, thread, siginfo);
|
|
|
|
|
|
+ need_schedule = _siginfo_deliver_to_thread(thread, siginfo);
|
|
ret = 0;
|
|
ret = 0;
|
|
}
|
|
}
|
|
else
|
|
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,
|
|
rt_err_t lwp_thread_signal_timedwait(rt_thread_t thread, lwp_sigset_t *sigset,
|
|
siginfo_t *usi, struct timespec *timeout)
|
|
siginfo_t *usi, struct timespec *timeout)
|
|
{
|
|
{
|
|
- LOG_D("%s", __func__);
|
|
|
|
-
|
|
|
|
rt_base_t level;
|
|
rt_base_t level;
|
|
rt_err_t ret;
|
|
rt_err_t ret;
|
|
|
|
+ lwp_sigset_t saved_sigset;
|
|
|
|
+ lwp_sigset_t blocked_sigset;
|
|
int sig;
|
|
int sig;
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -960,6 +967,7 @@ rt_err_t lwp_thread_signal_timedwait(rt_thread_t thread, lwp_sigset_t *sigset,
|
|
_sigdelset(sigset, SIGSTOP);
|
|
_sigdelset(sigset, SIGSTOP);
|
|
_signotsets(sigset, sigset);
|
|
_signotsets(sigset, sigset);
|
|
|
|
|
|
|
|
+
|
|
/* FIXME: acquire READ lock to lwp */
|
|
/* FIXME: acquire READ lock to lwp */
|
|
level = rt_hw_interrupt_disable();
|
|
level = rt_hw_interrupt_disable();
|
|
sig = _dequeue_signal(thread, sigset, usi);
|
|
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)
|
|
if (sig)
|
|
return sig;
|
|
return sig;
|
|
|
|
|
|
- /* WARNING atomic problem, what if pending signal arrives before we sleep */
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* @brief POSIX
|
|
* @brief POSIX
|
|
* if none of the signals specified by set are pending, sigtimedwait() shall
|
|
* if none of the signals specified by set are pending, sigtimedwait() shall
|
|
* wait for the time interval specified in the timespec structure referenced
|
|
* wait for the time interval specified in the timespec structure referenced
|
|
* by timeout.
|
|
* 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)
|
|
if (timeout)
|
|
{
|
|
{
|
|
- /* TODO: verify timeout valid ? not overflow 32bits, nanosec valid, ... */
|
|
|
|
rt_uint32_t time;
|
|
rt_uint32_t time;
|
|
time = rt_timespec_to_tick(timeout);
|
|
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)
|
|
if (ret == RT_EOK)
|
|
{
|
|
{
|
|
rt_schedule();
|
|
rt_schedule();
|
|
- ret = -EAGAIN;
|
|
|
|
|
|
+ /* If thread->error reliable? */
|
|
|
|
+ if (thread->error == -RT_EINTR)
|
|
|
|
+ ret = -EINTR;
|
|
|
|
+ else
|
|
|
|
+ ret = -EAGAIN;
|
|
}
|
|
}
|
|
/* else ret == -EINTR */
|
|
/* else ret == -EINTR */
|
|
|
|
+ _thread_signal_mask(thread, LWP_SIG_MASK_CMD_SET_MASK, &saved_sigset, RT_NULL);
|
|
|
|
|
|
/* FIXME: acquire READ lock to lwp */
|
|
/* FIXME: acquire READ lock to lwp */
|
|
level = rt_hw_interrupt_disable();
|
|
level = rt_hw_interrupt_disable();
|