mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-23 17:33:23 +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()
|
||||
}
|
||||
|
||||
pub fn has_pending_signal(&self) -> bool {
|
||||
!self.sig_queues.is_empty()
|
||||
/// Returns whether the thread has some pending signals
|
||||
/// 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.
|
||||
|
@ -111,25 +111,28 @@ impl Pauser {
|
||||
{
|
||||
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 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);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
@ -159,6 +162,7 @@ impl Pauser {
|
||||
};
|
||||
|
||||
posix_thread.unregiser_sigqueue_observer(&observer);
|
||||
posix_thread.sig_mask().lock().set(old_mask.as_u64());
|
||||
|
||||
match res? {
|
||||
Res::Ok(r) => Ok(r),
|
||||
|
@ -61,11 +61,17 @@ impl SigQueues {
|
||||
signal
|
||||
}
|
||||
|
||||
/// Returns the pending signals
|
||||
pub fn sig_pending(&self) -> SigSet {
|
||||
let queues = self.queues.lock();
|
||||
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(
|
||||
&self,
|
||||
observer: Weak<dyn Observer<SigEvents>>,
|
||||
@ -189,6 +195,15 @@ impl Queues {
|
||||
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>> {
|
||||
debug_assert!(signum.is_std());
|
||||
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
|
||||
pub fn create_new_user_task(user_space: Arc<UserSpace>, thread_ref: Weak<Thread>) -> Arc<Task> {
|
||||
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_task = current_thread.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()
|
||||
);
|
||||
|
||||
#[allow(clippy::redundant_closure)]
|
||||
let has_kernel_event_fn = || has_pending_signal(¤t_thread);
|
||||
let posix_thread = current_thread.as_posix_thread().unwrap();
|
||||
let has_kernel_event_fn = || posix_thread.has_pending();
|
||||
loop {
|
||||
let return_reason = user_mode.execute(has_kernel_event_fn);
|
||||
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::KernelEvent => {}
|
||||
};
|
||||
// should be do this comparison before handle signal?
|
||||
|
||||
if current_thread.status().is_exited() {
|
||||
break;
|
||||
}
|
||||
|
Reference in New Issue
Block a user