use alloc::{
sync::{Arc, Weak},
vec::Vec,
};
use core::{any::Any, fmt};
use ax_kspin::SpinNoIrq;
use weak_map::WeakMap;
use crate::{Pid, ProcessGroup};
pub struct Session {
sid: Pid,
pub(crate) process_groups: SpinNoIrq<WeakMap<Pid, Weak<ProcessGroup>>>,
terminal: SpinNoIrq<Option<Arc<dyn Any + Send + Sync>>>,
}
impl Session {
pub(crate) fn new(sid: Pid) -> Arc<Self> {
Arc::new(Self {
sid,
process_groups: SpinNoIrq::new(WeakMap::new()),
terminal: SpinNoIrq::new(None),
})
}
}
impl Session {
pub fn sid(&self) -> Pid {
self.sid
}
pub fn process_groups(&self) -> Vec<Arc<ProcessGroup>> {
self.process_groups.lock().values().collect()
}
pub fn set_terminal_with(&self, terminal: impl FnOnce() -> Arc<dyn Any + Send + Sync>) -> bool {
let mut guard = self.terminal.lock();
if guard.is_some() {
return false;
}
*guard = Some(terminal());
true
}
pub fn unset_terminal(&self, term: &Arc<dyn Any + Send + Sync>) -> bool {
let mut guard = self.terminal.lock();
if guard.as_ref().is_some_and(|it| Arc::ptr_eq(it, term)) {
*guard = None;
true
} else {
false
}
}
pub fn terminal(&self) -> Option<Arc<dyn Any + Send + Sync>> {
self.terminal.lock().clone()
}
}
impl fmt::Debug for Session {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Session({})", self.sid)
}
}