Add enqueue_signal_async

This commit is contained in:
Ruihan Li 2025-04-19 18:24:08 +08:00 committed by Tate, Hongliang Tian
parent c56aee92f4
commit 9e2dde5ebb
3 changed files with 29 additions and 12 deletions

View File

@ -15,7 +15,7 @@ use crate::{
prelude::*,
process::{
posix_thread::FileTableRefMut,
signal::{constants::SIGIO, signals::kernel::KernelSignal, PollAdaptor},
signal::{constants::SIGIO, PollAdaptor},
Pid, Process,
},
};
@ -405,10 +405,8 @@ impl OwnerObserver {
impl Observer<IoEvents> for OwnerObserver {
fn on_events(&self, _events: &IoEvents) {
if self.file.status_flags().contains(StatusFlags::O_ASYNC)
&& let Some(process) = self.owner.upgrade()
{
process.enqueue_signal(KernelSignal::new(SIGIO));
if self.file.status_flags().contains(StatusFlags::O_ASYNC) {
crate::process::enqueue_signal_async(self.owner.clone(), SIGIO);
}
}
}

View File

@ -23,8 +23,8 @@ pub use clone::{clone_child, CloneArgs, CloneFlags};
pub use credentials::{Credentials, Gid, Uid};
pub use kill::{kill, kill_all, kill_group, tgkill};
pub use process::{
spawn_init_process, ExitCode, JobControl, Pgid, Pid, Process, ProcessGroup, Session, Sid,
Terminal,
enqueue_signal_async, spawn_init_process, ExitCode, JobControl, Pgid, Pid, Process,
ProcessGroup, Session, Sid, Terminal,
};
pub use process_filter::ProcessFilter;
pub use process_vm::{

View File

@ -600,14 +600,15 @@ impl Process {
&self.sig_dispositions
}
/// Enqueues a process-directed signal. This method should only be used for enqueue kernel
/// signal and fault signal.
/// Enqueues a process-directed signal.
///
/// This method should only be used for enqueue kernel signals and fault signals.
///
/// The signal may be delivered to any one of the threads that does not currently have the
/// signal blocked. If more than one of the threads has the signal unblocked, then this method
/// signal blocked. If more than one of the threads have the signal unblocked, then this method
/// chooses an arbitrary thread to which to deliver the signal.
///
/// TODO: restrict these method with access control tool.
//
// TODO: Restrict this method with the access control tool.
pub fn enqueue_signal(&self, signal: impl Signal + Clone + 'static) {
if self.status.is_zombie() {
return;
@ -706,3 +707,21 @@ impl Process {
}
}
}
/// Enqueues a process-directed kernel signal asynchronously.
///
/// This is the asynchronous version of [`Process::enqueue_signal`]. By asynchronous, this method
/// submits a work item and returns, so this method doesn't sleep and can be used in atomic mode.
pub fn enqueue_signal_async(process: Weak<Process>, signum: SigNum) {
use super::signal::signals::kernel::KernelSignal;
use crate::thread::work_queue;
work_queue::submit_work_func(
move || {
if let Some(process) = process.upgrade() {
process.enqueue_signal(KernelSignal::new(signum));
}
},
work_queue::WorkPriority::High,
);
}