Send event on thread death.
This commit is contained in:
@@ -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<Frame>,
|
||||
|
||||
// TODO: id can reappear after wraparound?
|
||||
pub owner_proc_id: Option<NonZeroUsize>,
|
||||
|
||||
// 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<Context> {
|
||||
pub fn new(owner_proc_id: Option<NonZeroUsize>) -> Result<Context> {
|
||||
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,
|
||||
|
||||
+11
-4
@@ -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<BTreeSet<ContextRef>> = 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<Arc<RwSpinlock<Context>>> {
|
||||
pub fn spawn(
|
||||
userspace_allowed: bool,
|
||||
owner_proc_id: Option<NonZeroUsize>,
|
||||
func: extern "C" fn(),
|
||||
) -> Result<Arc<RwSpinlock<Context>>> {
|
||||
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()
|
||||
|
||||
+2
-1
@@ -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();
|
||||
|
||||
+13
-1
@@ -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)),
|
||||
};
|
||||
|
||||
+1
-2
@@ -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<usize> into -errno
|
||||
|
||||
+21
-5
@@ -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!();
|
||||
|
||||
Reference in New Issue
Block a user