From f40ec48b3eff35d09555320f7a1f54c5babdcf95 Mon Sep 17 00:00:00 2001
From: 4lDO2 <4lDO2@protonmail.com>
Date: Fri, 21 Feb 2025 11:53:38 +0100
Subject: [PATCH] Send event on thread death.
---
src/context/context.rs | 9 +++++++--
src/context/mod.rs | 15 +++++++++++----
src/main.rs | 3 ++-
src/scheme/proc.rs | 14 +++++++++++++-
src/syscall/mod.rs | 3 +--
src/syscall/process.rs | 26 +++++++++++++++++++++-----
6 files changed, 55 insertions(+), 15 deletions(-)
diff --git a/src/context/context.rs b/src/context/context.rs
index 65fbaf3982..0ce5601a37 100644
--- a/src/context/context.rs
+++ b/src/context/context.rs
@@ -25,6 +25,7 @@ use crate::syscall::error::{Error, Result, EAGAIN, ESRCH};
use super::{
empty_cr3,
+ file::FileDescription,
memory::{AddrSpaceWrapper, GrantFileRef},
};
@@ -120,6 +121,9 @@ pub struct Context {
pub being_sigkilled: bool,
pub fmap_ret: Option,
+ // TODO: id can reappear after wraparound?
+ pub owner_proc_id: Option,
+
// TODO: Temporary replacement for existing kernel logic, replace with capabilities!
pub ens: SchemeNamespace,
pub euid: u32,
@@ -145,9 +149,9 @@ pub struct SignalState {
}
impl Context {
- pub fn new() -> Result {
+ pub fn new(owner_proc_id: Option) -> Result {
static DEBUG_ID: AtomicU32 = AtomicU32::new(1);
- let this = Context {
+ let this = Self {
debug_id: DEBUG_ID.fetch_add(1, Ordering::Relaxed),
sig: None,
status: Status::HardBlocked {
@@ -172,6 +176,7 @@ impl Context {
userspace: false,
fmap_ret: None,
being_sigkilled: false,
+ owner_proc_id,
ens: 0.into(),
euid: u32::MAX,
diff --git a/src/context/mod.rs b/src/context/mod.rs
index 61f4795584..7d67b4f08e 100644
--- a/src/context/mod.rs
+++ b/src/context/mod.rs
@@ -2,6 +2,8 @@
//!
//! For resources on contexts, please consult [wikipedia](https://en.wikipedia.org/wiki/Context_switch) and [osdev](https://wiki.osdev.org/Context_Switching)
+use core::num::NonZeroUsize;
+
use alloc::{borrow::Cow, collections::BTreeSet, sync::Arc};
use spin::{RwLock, RwLockReadGuard, RwLockWriteGuard};
@@ -68,7 +70,8 @@ pub use self::arch::empty_cr3;
static CONTEXTS: RwLock> = RwLock::new(BTreeSet::new());
pub fn init() {
- let mut context = Context::new().expect("failed to create kmain context");
+ let owner = None; // kmain not owned by any fd
+ let mut context = Context::new(owner).expect("failed to create kmain context");
context.sched_affinity = LogicalCpuSet::empty();
context.sched_affinity.atomic_set(crate::cpu_id());
context.name = Cow::Borrowed("kmain");
@@ -140,11 +143,15 @@ impl PartialEq for ContextRef {
impl Eq for ContextRef {}
/// Spawn a context from a function.
-pub fn spawn(userspace_allowed: bool, func: extern "C" fn()) -> Result>> {
+pub fn spawn(
+ userspace_allowed: bool,
+ owner_proc_id: Option,
+ func: extern "C" fn(),
+) -> Result>> {
let stack = Kstack::new()?;
- let context_lock =
- Arc::try_new(RwSpinlock::new(Context::new()?)).map_err(|_| Error::new(ENOMEM))?;
+ let context_lock = Arc::try_new(RwSpinlock::new(Context::new(owner_proc_id)?))
+ .map_err(|_| Error::new(ENOMEM))?;
CONTEXTS
.write()
diff --git a/src/main.rs b/src/main.rs
index e60f2e3e40..acb2a3579c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -204,7 +204,8 @@ fn kmain(cpu_count: u32, bootstrap: Bootstrap) -> ! {
#[cfg(feature = "profiling")]
profiling::ready_for_profiling();
- match context::spawn(true, userspace_init) {
+ let owner = None; // kmain not owned by any fd
+ match context::spawn(true, owner, userspace_init) {
Ok(context_lock) => {
{
let mut context = context_lock.write();
diff --git a/src/scheme/proc.rs b/src/scheme/proc.rs
index 9dc0ed6597..6ae144362c 100644
--- a/src/scheme/proc.rs
+++ b/src/scheme/proc.rs
@@ -266,7 +266,19 @@ impl ProcScheme {
OpenTy::Auth => {
extern "C" fn ret() {}
let context = match operation_str.ok_or(Error::new(ENOENT))? {
- "new-context" => context::spawn(true, ret)?,
+ "new-context" => {
+ let id = NonZeroUsize::new(NEXT_ID.fetch_add(1, Ordering::Relaxed))
+ .ok_or(Error::new(EMFILE))?;
+ let context = context::spawn(true, Some(id), ret)?;
+ HANDLES.write().insert(
+ id.get(),
+ Handle {
+ context,
+ kind: ContextHandle::OpenViaDup,
+ },
+ );
+ return Ok((id.get(), InternalFlags::empty()));
+ }
"cur-context" => context::current(),
_ => return Err(Error::new(ENOENT)),
};
diff --git a/src/syscall/mod.rs b/src/syscall/mod.rs
index bdedd328e6..42e10f065b 100644
--- a/src/syscall/mod.rs
+++ b/src/syscall/mod.rs
@@ -227,8 +227,7 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> us
percpu.inside_syscall.set(false);
if percpu.switch_internals.being_sigkilled.get() {
- todo!()
- //exit(SIGKILL);
+ exit_this_context();
}
// errormux turns Result into -errno
diff --git a/src/syscall/process.rs b/src/syscall/process.rs
index 62e96ef4f6..f89ab10453 100644
--- a/src/syscall/process.rs
+++ b/src/syscall/process.rs
@@ -2,15 +2,20 @@ use alloc::{collections::VecDeque, sync::Arc, vec::Vec};
use core::{mem, num::NonZeroUsize, sync::atomic::Ordering};
use spinning_top::RwSpinlock;
use syscall::{
- sig_bit, RtSigInfo, SenderInfo, SIGCHLD, SIGKILL, SIGSTOP, SIGTERM, SIGTSTP, SIGTTIN, SIGTTOU,
+ sig_bit, EventFlags, RtSigInfo, SenderInfo, SIGCHLD, SIGKILL, SIGSTOP, SIGTERM, SIGTSTP,
+ SIGTTIN, SIGTTOU,
};
use rmm::Arch;
use spin::RwLock;
-use crate::context::{
- memory::{AddrSpace, Grant, PageSpan},
- Context, ContextRef,
+use crate::{
+ context::{
+ memory::{AddrSpace, Grant, PageSpan},
+ Context, ContextRef,
+ },
+ event,
+ scheme::GlobalSchemes,
};
use crate::{
@@ -47,7 +52,18 @@ pub fn exit_this_context() -> ! {
}
drop(addrspace_opt);
// TODO: Should status == Status::HardBlocked be handled differently?
- context_lock.write().status = context::Status::Dead;
+ let owner = {
+ let mut guard = context_lock.write();
+ guard.status = context::Status::Dead;
+ guard.owner_proc_id
+ };
+ if let Some(owner) = owner {
+ let _ = event::trigger(
+ GlobalSchemes::Proc.scheme_id(),
+ owner.get(),
+ EventFlags::EVENT_READ,
+ );
+ }
let _ = context::contexts_mut().remove(&ContextRef(context_lock));
context::switch();
unreachable!();