* Fixed the kernel bug that prevented SIGCONT from working properly: the problem
occured if SIGSTOP was already delivered but not yet handled when SIGCONT was sent. Now, SIGCONT will clear all stop signals from the pending signals. * SIGTSTP, SIGTTIN, and SIGTTOU are supposed to suspend the thread as well, adapted the default behaviour to respect that. * Removed the work-around from r21997 TermParse.cpp for this exact problem. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22004 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
f7e1df7560
commit
871d97a9f5
@ -225,12 +225,11 @@ TermParse::StopPtyReader()
|
||||
}
|
||||
|
||||
if (fReaderThread >= 0) {
|
||||
status_t dummy;
|
||||
//suspend_thread(fReaderThread);
|
||||
// TODO: interrupt read() - doesn't work for whatever reason
|
||||
//wait_for_thread(fReaderThread, &dummy);
|
||||
kill_thread(fReaderThread);
|
||||
|
||||
suspend_thread(fReaderThread);
|
||||
|
||||
status_t status;
|
||||
wait_for_thread(fReaderThread, &status);
|
||||
|
||||
fReaderThread = -1;
|
||||
}
|
||||
}
|
||||
|
@ -32,8 +32,12 @@
|
||||
|
||||
#define SIGNAL_TO_MASK(signal) (1LL << (signal - 1))
|
||||
#define BLOCKABLE_SIGNALS (~(KILL_SIGNALS | SIGNAL_TO_MASK(SIGSTOP)))
|
||||
#define STOP_SIGNALS \
|
||||
(SIGNAL_TO_MASK(SIGSTOP) | SIGNAL_TO_MASK(SIGTSTP) \
|
||||
| SIGNAL_TO_MASK(SIGTTIN) | SIGNAL_TO_MASK(SIGTTOU))
|
||||
#define DEFAULT_IGNORE_SIGNALS \
|
||||
(SIGNAL_TO_MASK(SIGCHLD) | SIGNAL_TO_MASK(SIGWINCH) | SIGNAL_TO_MASK(SIGCONT))
|
||||
(SIGNAL_TO_MASK(SIGCHLD) | SIGNAL_TO_MASK(SIGWINCH) \
|
||||
| SIGNAL_TO_MASK(SIGCONT))
|
||||
|
||||
|
||||
const char * const sigstr[NSIG] = {
|
||||
@ -128,9 +132,6 @@ handle_signals(struct thread *thread)
|
||||
switch (signal) {
|
||||
case SIGCHLD:
|
||||
case SIGWINCH:
|
||||
case SIGTSTP:
|
||||
case SIGTTIN:
|
||||
case SIGTTOU:
|
||||
case SIGCONT:
|
||||
case SIGURG:
|
||||
// notify the debugger
|
||||
@ -139,6 +140,9 @@ handle_signals(struct thread *thread)
|
||||
continue;
|
||||
|
||||
case SIGSTOP:
|
||||
case SIGTSTP:
|
||||
case SIGTTIN:
|
||||
case SIGTTOU:
|
||||
// notify the debugger
|
||||
if (debugSignal
|
||||
&& !notify_debugger(thread, signal, handler, false))
|
||||
@ -212,7 +216,8 @@ handle_signals(struct thread *thread)
|
||||
bool
|
||||
is_kill_signal_pending(void)
|
||||
{
|
||||
return (atomic_get(&thread_get_current_thread()->sig_pending) & KILL_SIGNALS) != 0;
|
||||
return (atomic_get(&thread_get_current_thread()->sig_pending)
|
||||
& KILL_SIGNALS) != 0;
|
||||
}
|
||||
|
||||
|
||||
@ -267,16 +272,21 @@ deliver_signal(struct thread *thread, uint signal, uint32 flags)
|
||||
} else if (thread->state == B_THREAD_WAITING)
|
||||
sem_interrupt_thread(thread);
|
||||
break;
|
||||
|
||||
case SIGCONT:
|
||||
// Wake up thread if it was suspended
|
||||
if (thread->state == B_THREAD_SUSPENDED) {
|
||||
thread->state = thread->next_state = B_THREAD_READY;
|
||||
scheduler_enqueue_in_run_queue(thread);
|
||||
}
|
||||
|
||||
atomic_and(&thread->sig_pending, ~STOP_SIGNALS);
|
||||
// remove any pending stop signals
|
||||
break;
|
||||
|
||||
default:
|
||||
if (thread->sig_pending & (~thread->sig_block_mask | SIGNAL_TO_MASK(SIGCHLD))) {
|
||||
if (thread->sig_pending
|
||||
& (~thread->sig_block_mask | SIGNAL_TO_MASK(SIGCHLD))) {
|
||||
// Interrupt thread if it was waiting
|
||||
if (thread->state == B_THREAD_WAITING)
|
||||
sem_interrupt_thread(thread);
|
||||
|
@ -1529,7 +1529,7 @@ wait_for_thread_etc(thread_id id, uint32 flags, bigtime_t timeout,
|
||||
|
||||
if (thread == NULL) {
|
||||
// we couldn't find this thread - maybe it's already gone, and we'll
|
||||
// find its death entry
|
||||
// find its death entry in our team
|
||||
GRAB_TEAM_LOCK();
|
||||
|
||||
status = team_get_death_entry(thread_get_current_thread()->team,
|
||||
|
Loading…
Reference in New Issue
Block a user