mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-24 01:43:22 +00:00
Check only not blocked signals in Pauser
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
5cde55da3d
commit
6f3a483be6
@ -101,8 +101,11 @@ impl PosixThread {
|
|||||||
self.sig_queues.sig_pending()
|
self.sig_queues.sig_pending()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_pending_signal(&self) -> bool {
|
/// Returns whether the thread has some pending signals
|
||||||
!self.sig_queues.is_empty()
|
/// that are not blocked.
|
||||||
|
pub fn has_pending(&self) -> bool {
|
||||||
|
let blocked = *self.sig_mask().lock();
|
||||||
|
self.sig_queues.has_pending(blocked)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether the signal is blocked by the thread.
|
/// Returns whether the signal is blocked by the thread.
|
||||||
|
@ -111,25 +111,28 @@ impl Pauser {
|
|||||||
{
|
{
|
||||||
self.is_interrupted.store(false, Ordering::Release);
|
self.is_interrupted.store(false, Ordering::Release);
|
||||||
|
|
||||||
// Register observer on sigqueue
|
|
||||||
let observer = Arc::downgrade(self) as Weak<dyn Observer<SigEvents>>;
|
|
||||||
let filter = {
|
|
||||||
let sig_mask = {
|
|
||||||
let current_thread = current_thread!();
|
|
||||||
let poxis_thread = current_thread.as_posix_thread().unwrap();
|
|
||||||
let mut current_sigmask = *poxis_thread.sig_mask().lock();
|
|
||||||
current_sigmask.block(self.sig_mask.as_u64());
|
|
||||||
current_sigmask
|
|
||||||
};
|
|
||||||
SigEventsFilter::new(sig_mask)
|
|
||||||
};
|
|
||||||
|
|
||||||
let current_thread = current_thread!();
|
let current_thread = current_thread!();
|
||||||
let posix_thread = current_thread.as_posix_thread().unwrap();
|
let posix_thread = current_thread.as_posix_thread().unwrap();
|
||||||
|
|
||||||
|
// Block `self.sig_mask`
|
||||||
|
let (old_mask, filter) = {
|
||||||
|
let mut current_mask = posix_thread.sig_mask().lock();
|
||||||
|
let old_mask = *current_mask;
|
||||||
|
|
||||||
|
let new_mask = {
|
||||||
|
current_mask.block(self.sig_mask.as_u64());
|
||||||
|
*current_mask
|
||||||
|
};
|
||||||
|
|
||||||
|
(old_mask, SigEventsFilter::new(new_mask))
|
||||||
|
};
|
||||||
|
|
||||||
|
// Register observer on sigqueue
|
||||||
|
let observer = Arc::downgrade(self) as Weak<dyn Observer<SigEvents>>;
|
||||||
posix_thread.register_sigqueue_observer(observer.clone(), filter);
|
posix_thread.register_sigqueue_observer(observer.clone(), filter);
|
||||||
|
|
||||||
// Some signal may come before we register observer, so we do another check here.
|
// Some signal may come before we register observer, so we do another check here.
|
||||||
if posix_thread.has_pending_signal() {
|
if posix_thread.has_pending_signals() {
|
||||||
self.is_interrupted.store(true, Ordering::Release);
|
self.is_interrupted.store(true, Ordering::Release);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,6 +162,7 @@ impl Pauser {
|
|||||||
};
|
};
|
||||||
|
|
||||||
posix_thread.unregiser_sigqueue_observer(&observer);
|
posix_thread.unregiser_sigqueue_observer(&observer);
|
||||||
|
posix_thread.sig_mask().lock().set(old_mask.as_u64());
|
||||||
|
|
||||||
match res? {
|
match res? {
|
||||||
Res::Ok(r) => Ok(r),
|
Res::Ok(r) => Ok(r),
|
||||||
|
@ -61,11 +61,17 @@ impl SigQueues {
|
|||||||
signal
|
signal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the pending signals
|
||||||
pub fn sig_pending(&self) -> SigSet {
|
pub fn sig_pending(&self) -> SigSet {
|
||||||
let queues = self.queues.lock();
|
let queues = self.queues.lock();
|
||||||
queues.sig_pending()
|
queues.sig_pending()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether there's some pending signals that are not blocked
|
||||||
|
pub fn has_pending(&self, blocked: SigMask) -> bool {
|
||||||
|
self.queues.lock().has_pending(blocked)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn register_observer(
|
pub fn register_observer(
|
||||||
&self,
|
&self,
|
||||||
observer: Weak<dyn Observer<SigEvents>>,
|
observer: Weak<dyn Observer<SigEvents>>,
|
||||||
@ -189,6 +195,15 @@ impl Queues {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether the `SigQueues` has some pending signals which are not blocked
|
||||||
|
fn has_pending(&self, blocked: SigMask) -> bool {
|
||||||
|
self.std_queues.iter().any(|signal| {
|
||||||
|
signal
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|signal| !blocked.contains(signal.num()))
|
||||||
|
}) || self.rt_queues.iter().any(|rt_queue| !rt_queue.is_empty())
|
||||||
|
}
|
||||||
|
|
||||||
fn get_std_queue_mut(&mut self, signum: SigNum) -> &mut Option<Box<dyn Signal>> {
|
fn get_std_queue_mut(&mut self, signum: SigNum) -> &mut Option<Box<dyn Signal>> {
|
||||||
debug_assert!(signum.is_std());
|
debug_assert!(signum.is_std());
|
||||||
let idx = (signum.as_u8() - MIN_STD_SIG_NUM) as usize;
|
let idx = (signum.as_u8() - MIN_STD_SIG_NUM) as usize;
|
||||||
|
@ -17,11 +17,6 @@ use crate::{
|
|||||||
/// create new task with userspace and parent process
|
/// create new task with userspace and parent process
|
||||||
pub fn create_new_user_task(user_space: Arc<UserSpace>, thread_ref: Weak<Thread>) -> Arc<Task> {
|
pub fn create_new_user_task(user_space: Arc<UserSpace>, thread_ref: Weak<Thread>) -> Arc<Task> {
|
||||||
fn user_task_entry() {
|
fn user_task_entry() {
|
||||||
fn has_pending_signal(current_thread: &Arc<Thread>) -> bool {
|
|
||||||
let posix_thread = current_thread.as_posix_thread().unwrap();
|
|
||||||
posix_thread.has_pending_signal()
|
|
||||||
}
|
|
||||||
|
|
||||||
let current_thread = current_thread!();
|
let current_thread = current_thread!();
|
||||||
let current_task = current_thread.task();
|
let current_task = current_thread.task();
|
||||||
let user_space = current_task
|
let user_space = current_task
|
||||||
@ -41,8 +36,8 @@ pub fn create_new_user_task(user_space: Arc<UserSpace>, thread_ref: Weak<Thread>
|
|||||||
user_mode.context().syscall_ret()
|
user_mode.context().syscall_ret()
|
||||||
);
|
);
|
||||||
|
|
||||||
#[allow(clippy::redundant_closure)]
|
let posix_thread = current_thread.as_posix_thread().unwrap();
|
||||||
let has_kernel_event_fn = || has_pending_signal(¤t_thread);
|
let has_kernel_event_fn = || posix_thread.has_pending();
|
||||||
loop {
|
loop {
|
||||||
let return_reason = user_mode.execute(has_kernel_event_fn);
|
let return_reason = user_mode.execute(has_kernel_event_fn);
|
||||||
let context = user_mode.context_mut();
|
let context = user_mode.context_mut();
|
||||||
@ -52,7 +47,7 @@ pub fn create_new_user_task(user_space: Arc<UserSpace>, thread_ref: Weak<Thread>
|
|||||||
ReturnReason::UserSyscall => handle_syscall(context),
|
ReturnReason::UserSyscall => handle_syscall(context),
|
||||||
ReturnReason::KernelEvent => {}
|
ReturnReason::KernelEvent => {}
|
||||||
};
|
};
|
||||||
// should be do this comparison before handle signal?
|
|
||||||
if current_thread.status().is_exited() {
|
if current_thread.status().is_exited() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user