signal: If the thread receiving the signal is not current, the signal is not processed.

This commit is contained in:
Tomoki Shirasawa
2018-01-25 22:27:34 +09:00
parent 1fa398cfab
commit f55f01cc11
2 changed files with 59 additions and 28 deletions

View File

@ -875,8 +875,9 @@ void interrupt_exit(struct x86_user_context *regs)
{ {
if (interrupt_from_user(regs)) { if (interrupt_from_user(regs)) {
cpu_enable_interrupt(); cpu_enable_interrupt();
check_signal(0, regs, 0); check_sig_pending();
check_need_resched(); check_need_resched();
check_signal(0, regs, 0);
} }
else { else {
check_sig_pending(); check_sig_pending();

View File

@ -1055,10 +1055,9 @@ out:
return; return;
} }
void static int
check_sig_pending() check_sig_pending_thread(struct thread *thread)
{ {
struct thread *thread;
int found = 0; int found = 0;
struct list_head *head; struct list_head *head;
mcs_rwlock_lock_t *lock; mcs_rwlock_lock_t *lock;
@ -1067,22 +1066,11 @@ check_sig_pending()
struct sig_pending *pending; struct sig_pending *pending;
__sigset_t w; __sigset_t w;
__sigset_t x; __sigset_t x;
int sig; int sig = 0;
struct k_sigaction *k; struct k_sigaction *k;
struct cpu_local_var *v;
v = get_this_cpu_local_var();
if(clv == NULL)
return;
thread = cpu_local_var(current);
if (thread == NULL || thread == &cpu_local_var(idle)) {
return;
}
if (thread->in_syscall_offload == 0) {
return;
}
w = thread->sigmask.__val[0]; w = thread->sigmask.__val[0];
lock = &thread->sigcommon->lock; lock = &thread->sigcommon->lock;
@ -1101,6 +1089,12 @@ check_sig_pending()
if (pending->interrupted == 0) { if (pending->interrupted == 0) {
pending->interrupted = 1; pending->interrupted = 1;
found = 1; found = 1;
if (sig != SIGCHLD &&
sig != SIGURG &&
!k->sa.sa_handler) {
found = 2;
break;
}
} }
} }
} }
@ -1108,6 +1102,10 @@ check_sig_pending()
mcs_rwlock_reader_unlock(lock, &mcs_rw_node); mcs_rwlock_reader_unlock(lock, &mcs_rw_node);
if (found == 2) {
break;
}
if (lock == &thread->sigpendinglock) { if (lock == &thread->sigpendinglock) {
break; break;
} }
@ -1116,17 +1114,49 @@ check_sig_pending()
head = &thread->sigpending; head = &thread->sigpending;
} }
if (found) { if (found == 2) {
if (sig != SIGCHLD && sig != SIGURG && ihk_mc_spinlock_unlock(&v->runq_lock, v->runq_irqstate);
thread->sigcommon->action[sig - 1].sa.sa_handler == NULL) {
terminate_mcexec(0, sig); terminate_mcexec(0, sig);
return 1;
} }
else if (thread->sigcommon->action[sig - 1].sa.sa_handler && else if (found == 1) {
thread->sigcommon->action[sig - 1].sa.sa_handler != ihk_mc_spinlock_unlock(&v->runq_lock, v->runq_irqstate);
(void *)1) {
interrupt_syscall(thread, 0); interrupt_syscall(thread, 0);
return 1;
} }
return 0;
} }
void
check_sig_pending()
{
struct thread *thread;
struct cpu_local_var *v;
if (clv == NULL)
return;
v = get_this_cpu_local_var();
repeat:
v->runq_irqstate = ihk_mc_spinlock_lock(&v->runq_lock);
list_for_each_entry(thread, &(v->runq), sched_list) {
if (thread == NULL || thread == &cpu_local_var(idle)) {
continue;
}
if (thread->in_syscall_offload == 0) {
continue;
}
if (thread->proc->exit_status & 0x0000000100000000L) {
continue;
}
if (check_sig_pending_thread(thread))
goto repeat;
}
ihk_mc_spinlock_unlock(&v->runq_lock, v->runq_irqstate);
} }
unsigned long unsigned long