mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-27 03:13:23 +00:00
Introduce a syscall restart mechanism
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
b70c4784ed
commit
ced0023d6b
@ -10,6 +10,7 @@ use ostd::sync::Waker;
|
||||
use super::{
|
||||
kill::SignalSenderIds,
|
||||
signal::{
|
||||
sig_action::SigAction,
|
||||
sig_mask::{AtomicSigMask, SigMask, SigSet},
|
||||
sig_num::SigNum,
|
||||
sig_queues::SigQueues,
|
||||
@ -220,8 +221,11 @@ impl PosixThread {
|
||||
/// Enqueues a thread-directed signal. This method should only be used for enqueue kernel
|
||||
/// signal and fault signal.
|
||||
pub fn enqueue_signal(&self, signal: Box<dyn Signal>) {
|
||||
let signal_number = signal.num();
|
||||
self.sig_queues.enqueue(signal);
|
||||
if let Some(waker) = &*self.signalled_waker.lock() {
|
||||
if self.process().sig_dispositions().lock().get(signal_number) != SigAction::Ign
|
||||
&& let Some(waker) = &*self.signalled_waker.lock()
|
||||
{
|
||||
waker.wake_up();
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ pub use sig_stack::{SigStack, SigStackFlags};
|
||||
|
||||
use super::posix_thread::PosixThread;
|
||||
use crate::{
|
||||
cpu::LinuxAbi,
|
||||
current_userspace,
|
||||
prelude::*,
|
||||
process::{do_exit_group, TermStatus},
|
||||
@ -41,7 +42,11 @@ pub trait SignalContext {
|
||||
// TODO: This interface of this method is error prone.
|
||||
// The method takes an argument for the current thread to optimize its efficiency.
|
||||
/// Handle pending signal for current process.
|
||||
pub fn handle_pending_signal(user_ctx: &mut UserContext, ctx: &Context) -> Result<()> {
|
||||
pub fn handle_pending_signal(
|
||||
user_ctx: &mut UserContext,
|
||||
ctx: &Context,
|
||||
syscall_number: Option<usize>,
|
||||
) -> Result<()> {
|
||||
// We first deal with signal in current thread, then signal in current process.
|
||||
let posix_thread = ctx.posix_thread;
|
||||
let signal = {
|
||||
@ -69,6 +74,17 @@ pub fn handle_pending_signal(user_ctx: &mut UserContext, ctx: &Context) -> Resul
|
||||
restorer_addr,
|
||||
mask,
|
||||
} => {
|
||||
if let Some(syscall_number) = syscall_number
|
||||
&& user_ctx.syscall_ret() == -(Errno::ERESTARTSYS as i32) as usize
|
||||
{
|
||||
if flags.contains(SigActionFlags::SA_RESTART) {
|
||||
user_ctx.set_syscall_num(syscall_number);
|
||||
user_ctx.set_instruction_pointer(user_ctx.instruction_pointer() - 2);
|
||||
} else {
|
||||
user_ctx.set_syscall_ret(-(Errno::EINTR as i32) as usize);
|
||||
}
|
||||
}
|
||||
|
||||
if flags.contains(SigActionFlags::SA_RESETHAND) {
|
||||
// In Linux, SA_RESETHAND corresponds to SA_ONESHOT,
|
||||
// which means the user handler will be executed only once and then reset to the default.
|
||||
|
@ -90,9 +90,6 @@ impl TryFrom<u32> for SigActionFlags {
|
||||
fn try_from(bits: u32) -> Result<Self> {
|
||||
let flags = SigActionFlags::from_bits(bits)
|
||||
.ok_or_else(|| Error::with_message(Errno::EINVAL, "invalid sig action flag"))?;
|
||||
if flags.contains(SigActionFlags::SA_RESTART) {
|
||||
warn!("SA_RESTART is not supported");
|
||||
}
|
||||
Ok(flags)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user