mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 03:47:35 +00:00
Kernel: Keep signal state in sync
In c3d231616c
we added the atomic variable
m_have_any_unmasked_pending_signals tracking the state of pending signals.
Add helper functions that automatically update this variable as needed.
This commit is contained in:
parent
dcc2c8a125
commit
92bfe40954
5 changed files with 84 additions and 19 deletions
|
@ -235,8 +235,7 @@ int Process::do_exec(NonnullRefPtr<FileDescription> main_program_description, Ve
|
|||
}
|
||||
|
||||
current_thread->set_default_signal_dispositions();
|
||||
current_thread->m_signal_mask = 0;
|
||||
current_thread->m_pending_signals = 0;
|
||||
current_thread->clear_signals();
|
||||
|
||||
m_futex_queues.clear();
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/ScopedValueRollback.h>
|
||||
#include <AK/ScopeGuard.h>
|
||||
#include <AK/Time.h>
|
||||
#include <Kernel/FileSystem/FileDescription.h>
|
||||
#include <Kernel/Process.h>
|
||||
|
@ -73,9 +73,14 @@ int Process::sys$select(const Syscall::SC_select_params* params)
|
|||
}
|
||||
|
||||
auto current_thread = Thread::current();
|
||||
ScopedValueRollback scoped_sigmask(current_thread->m_signal_mask);
|
||||
|
||||
u32 previous_signal_mask = 0;
|
||||
if (sigmask)
|
||||
current_thread->m_signal_mask = *sigmask;
|
||||
previous_signal_mask = current_thread->update_signal_mask(*sigmask);
|
||||
ScopeGuard rollback_signal_mask([&]() {
|
||||
if (sigmask)
|
||||
current_thread->update_signal_mask(previous_signal_mask);
|
||||
});
|
||||
|
||||
Thread::SelectBlocker::FDVector rfds;
|
||||
Thread::SelectBlocker::FDVector wfds;
|
||||
|
@ -187,9 +192,14 @@ int Process::sys$poll(Userspace<const Syscall::SC_poll_params*> user_params)
|
|||
}
|
||||
|
||||
auto current_thread = Thread::current();
|
||||
ScopedValueRollback scoped_sigmask(current_thread->m_signal_mask);
|
||||
|
||||
u32 previous_signal_mask = 0;
|
||||
if (params.sigmask)
|
||||
current_thread->m_signal_mask = sigmask;
|
||||
previous_signal_mask = current_thread->update_signal_mask(params.sigmask);
|
||||
ScopeGuard rollback_signal_mask([&]() {
|
||||
if (params.sigmask)
|
||||
current_thread->update_signal_mask(previous_signal_mask);
|
||||
});
|
||||
|
||||
#if defined(DEBUG_IO) || defined(DEBUG_POLL_SELECT)
|
||||
dbg() << "polling on (read:" << rfds.size() << ", write:" << wfds.size() << "), timeout=" << timeout.tv_sec << "s" << timeout.tv_nsec << "ns";
|
||||
|
|
|
@ -32,11 +32,7 @@ int Process::sys$sigprocmask(int how, Userspace<const sigset_t*> set, Userspace<
|
|||
{
|
||||
REQUIRE_PROMISE(sigaction);
|
||||
auto current_thread = Thread::current();
|
||||
if (old_set) {
|
||||
if (!validate_write_typed(old_set))
|
||||
return -EFAULT;
|
||||
copy_to_user(old_set, ¤t_thread->m_signal_mask);
|
||||
}
|
||||
u32 previous_signal_mask;
|
||||
if (set) {
|
||||
if (!validate_read_typed(set))
|
||||
return -EFAULT;
|
||||
|
@ -44,17 +40,24 @@ int Process::sys$sigprocmask(int how, Userspace<const sigset_t*> set, Userspace<
|
|||
copy_from_user(&set_value, set);
|
||||
switch (how) {
|
||||
case SIG_BLOCK:
|
||||
current_thread->m_signal_mask &= ~set_value;
|
||||
previous_signal_mask = current_thread->signal_mask_block(set_value, true);
|
||||
break;
|
||||
case SIG_UNBLOCK:
|
||||
current_thread->m_signal_mask |= set_value;
|
||||
previous_signal_mask = current_thread->signal_mask_block(set_value, false);
|
||||
break;
|
||||
case SIG_SETMASK:
|
||||
current_thread->m_signal_mask = set_value;
|
||||
previous_signal_mask = current_thread->update_signal_mask(set_value);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
previous_signal_mask = current_thread->signal_mask();
|
||||
}
|
||||
if (old_set) {
|
||||
if (!validate_write_typed(old_set))
|
||||
return -EFAULT;
|
||||
copy_to_user(old_set, &previous_signal_mask);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -64,7 +67,8 @@ int Process::sys$sigpending(Userspace<sigset_t*> set)
|
|||
REQUIRE_PROMISE(stdio);
|
||||
if (!validate_write_typed(set))
|
||||
return -EFAULT;
|
||||
copy_to_user(set, &Thread::current()->m_pending_signals);
|
||||
auto pending_signals = Thread::current()->pending_signals();
|
||||
copy_to_user(set, &pending_signals);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue