proc: re-enable signal delivery

This commit is contained in:
Mark Poliakov 2023-09-06 11:40:59 +03:00
parent 8ff58a48d2
commit 1719b84534
5 changed files with 55 additions and 28 deletions

View File

@ -73,8 +73,11 @@ pub mod combined {
impl CharDevice for CombinedTerminal {
fn read(&'static self, blocking: bool, data: &mut [u8]) -> Result<usize, Error> {
assert!(blocking);
block! {
match block! {
self.line_read(data).await
} {
Ok(res) => res,
Err(err) => Err(err),
}
// self.line_read(data)
}

View File

@ -64,9 +64,8 @@ fn syscall_handler(func: SyscallFunction, args: &[u64]) -> Result<usize, Error>
block! {
runtime::sleep(duration).await
};
Ok(0)
}
.map(|_| 0)
}
SyscallFunction::Exit => {
let code = ExitCode::from(args[0] as i32);
@ -317,8 +316,11 @@ fn syscall_handler(func: SyscallFunction, args: &[u64]) -> Result<usize, Error>
let target = Process::get(pid).ok_or(Error::DoesNotExist)?;
*status = block! {
*status = match block! {
Process::wait_for_exit(target).await
} {
Ok(status) => status,
Err(err) => return Err(err),
};
Ok(0)

View File

@ -247,14 +247,26 @@ impl Process {
return;
}
}
let current_state = self.state.swap(ProcessState::Ready, Ordering::SeqCst);
if current_state == ProcessState::Terminated {
todo!("Handle attempt to enqueue an already queued/running/terminated process");
} else if current_state == ProcessState::Suspended {
unsafe {
queue.enqueue(self);
match self.state.compare_exchange(
ProcessState::Suspended,
ProcessState::Ready,
Ordering::SeqCst,
Ordering::Relaxed,
) {
Err(ProcessState::Terminated) => {
// Process might've been killed while `await`ing in a `block!`
debugln!(
"Process {} {:?} already terminated, dropping",
self.id(),
self.name()
);
}
Err(state) => {
todo!("Unexpected process state when enqueueing: {:?}", state)
}
Ok(_) => unsafe {
queue.enqueue(self);
},
}
}
@ -355,17 +367,15 @@ impl Process {
}
/// Raises a signal for the currentprocess
pub fn raise_signal(self: &Arc<Self>, _signal: Signal) {
// XXX handle signals + async
todo!();
// {
// let mut inner = self.inner.lock();
// inner.signal_stack.push_back(signal);
// }
pub fn raise_signal(self: &Arc<Self>, signal: Signal) {
{
let mut inner = self.inner.lock();
inner.signal_stack.push_back(signal);
}
// if self.state() == ProcessState::Suspended {
// self.clone().enqueue_somewhere();
// }
if self.state() == ProcessState::Suspended {
self.clone().enqueue_somewhere();
}
}
/// Inherits the data from a parent process. Meant to be called from SpawnProcess handler.
@ -450,6 +460,17 @@ impl CurrentProcess {
inner.signal_entry.replace(SignalEntry { entry, stack });
}
pub fn suspend(&self) -> Result<(), Error> {
self.dequeue(ProcessState::Suspended);
let inner = self.inner.lock();
if !inner.signal_stack.is_empty() {
return Err(Error::Interrupted);
}
Ok(())
}
/// Terminate the current process
pub fn exit(&self, status: ExitCode) {
self.inner.lock().exit_status = status.into();

View File

@ -19,8 +19,6 @@ pub fn spawn_async_worker(index: usize) -> Result<(), Error> {
let name = format!("[async-worker-{}]", index);
spawn_kernel_closure(name, move || {
// let queue = TASK_QUEUE.or_init_with(task_queue::init_async_queue);
loop {
let task = task_queue::pop_task().unwrap(); // queue.block_pop().unwrap();
let mut future_slot = task.future.lock();
@ -41,7 +39,7 @@ pub fn spawn<F: Future<Output = ()> + Send + 'static>(future: F) -> Result<(), E
enqueue(Task::new(future))
}
pub fn run_to_completion<'a, T, F: Future<Output = T> + Send + 'a>(future: F) -> T {
pub fn run_to_completion<'a, T, F: Future<Output = T> + Send + 'a>(future: F) -> Result<T, Error> {
let process = Process::current();
let mut future = Box::pin(future);
@ -50,9 +48,11 @@ pub fn run_to_completion<'a, T, F: Future<Output = T> + Send + 'a>(future: F) ->
let context = &mut Context::from_waker(&waker);
match future.as_mut().poll(context) {
Poll::Ready(value) => break value,
Poll::Ready(value) => break Ok(value),
Poll::Pending => {
process.suspend();
if let Err(error) = process.suspend() {
break Err(error);
}
}
}
}

View File

@ -50,7 +50,8 @@ impl TaskQueue {
panic!("Pending worker queue overflow");
}
process.suspend();
// This must not fail. Signals must not be raised.
process.suspend().unwrap();
}
}
}