summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBernard Xiong <[email protected]>2019-02-21 04:51:39 +0800
committerBernard Xiong <[email protected]>2019-02-21 04:51:39 +0800
commit0574bf4153991246a39e68b71f96c500d2426970 (patch)
tree35ccaef3cc8ab008b692aa60e95f010e8586a3f1 /src
parent9dd2d94a8f1cb164605798a96aac57017f96ff88 (diff)
[Kernel] code cleanup for signal handling.
Disable interrupt to check thread->stat in _signal_entry to ensure the signal is not lost. At the same time, remove the disable interrupt return code from rt_thread_handle_sig function.
Diffstat (limited to 'src')
-rw-r--r--src/signal.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/src/signal.c b/src/signal.c
index 2bda02bb4f..1f7f3e50b3 100644
--- a/src/signal.c
+++ b/src/signal.c
@@ -48,22 +48,31 @@ static void _signal_default_handler(int signo)
static void _signal_entry(void *parameter)
{
+ register rt_base_t level;
rt_thread_t tid = rt_thread_self();
dbg_enter;
- /* handle signal */
- rt_thread_handle_sig(RT_FALSE);
+ while (1)
+ {
+ level = rt_hw_interrupt_disable();
+ if (tid->stat & RT_THREAD_STAT_SIGNAL)
+ {
+ rt_hw_interrupt_enable(level);
+ /* handle signal */
+ rt_thread_handle_sig(RT_FALSE);
+ }
+ else break;
+ }
/* never come back... */
- rt_hw_interrupt_disable();
- /* return to thread */
tid->sp = tid->sig_ret;
tid->sig_ret = RT_NULL;
LOG_D("switch back to: 0x%08x", tid->sp);
tid->stat &= ~RT_THREAD_STAT_SIGNAL;
+ /* return to thread */
rt_hw_context_switch_to((rt_uint32_t) & (tid->sp));
}
@@ -324,6 +333,7 @@ void rt_thread_handle_sig(rt_bool_t clean_state)
struct siginfo_node *si_node;
level = rt_hw_interrupt_disable();
+
if (tid->sig_pending & tid->sig_mask)
{
/* if thread is not waiting for signal */
@@ -364,10 +374,6 @@ void rt_thread_handle_sig(rt_bool_t clean_state)
{
tid->stat &= ~RT_THREAD_STAT_SIGNAL;
}
- else
- {
- return;
- }
}
}
rt_hw_interrupt_enable(level);