mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-08 04:56:43 +00:00
kernel: implement Disconnect() syscall
Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
parent
461d6f23ee
commit
85f0adbb2d
2 changed files with 48 additions and 2 deletions
|
|
@ -1525,6 +1525,42 @@ impl SystemServices {
|
|||
})
|
||||
}
|
||||
|
||||
/// Invalidate the provided connection ID.
|
||||
pub fn disconnect_from_server(&mut self, cid: CID) -> Result<(), xous_kernel::Error> {
|
||||
// Check to see if we've already connected to this server.
|
||||
// While doing this, find a free slot in case we haven't
|
||||
// yet connected.
|
||||
|
||||
// Slot indices are offset by two. Ensure we don't underflow.
|
||||
let slot_idx = cid;
|
||||
if slot_idx < 2 {
|
||||
klog!("CID {} is not valid", cid);
|
||||
return Err(xous_kernel::Error::ServerNotFound);
|
||||
}
|
||||
let slot_idx = (slot_idx - 2) as usize;
|
||||
let pid = crate::arch::process::current_pid();
|
||||
// klog!("KERNEL({}): Server table: {:?}", pid.get(), self.servers);
|
||||
ArchProcess::with_inner_mut(|process_inner| {
|
||||
assert_eq!(pid, process_inner.pid);
|
||||
if slot_idx >= process_inner.connection_map.len() {
|
||||
klog!("Slot index exceeds map length");
|
||||
return Err(xous_kernel::Error::ServerNotFound);
|
||||
}
|
||||
|
||||
// If the server ID is None, then we weren't connected in the first place.
|
||||
let idx = &mut process_inner.connection_map[slot_idx];
|
||||
if idx.is_none() {
|
||||
klog!("IDX[{}] is already None!", slot_idx);
|
||||
return Err(xous_kernel::Error::ServerNotFound);
|
||||
}
|
||||
|
||||
// Nullify this connection ID. It may now be reused.
|
||||
*idx = None;
|
||||
klog!("Removing server from table");
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
/// Retrieve the server ID index from the specified SID.
|
||||
/// This may only be called if the SID is a server owned by
|
||||
/// the current process.
|
||||
|
|
|
|||
|
|
@ -341,7 +341,11 @@ fn return_memory(
|
|||
// print!(" [waking up PID {}:{}]", client_pid, client_tid);
|
||||
ss.ready_thread(client_pid, client_tid)?;
|
||||
ss.switch_to_thread(client_pid, Some(client_tid))?;
|
||||
ss.set_thread_result(client_pid, client_tid, xous_kernel::Result::MemoryReturned(offset, valid))?;
|
||||
ss.set_thread_result(
|
||||
client_pid,
|
||||
client_tid,
|
||||
xous_kernel::Result::MemoryReturned(offset, valid),
|
||||
)?;
|
||||
|
||||
// Return success to the server
|
||||
Ok(xous_kernel::Result::Ok)
|
||||
|
|
@ -782,7 +786,9 @@ pub fn handle_inner(pid: PID, tid: TID, in_irq: bool, call: SysCall) -> SysCallR
|
|||
ss.connect_to_server(sid)
|
||||
.map(xous_kernel::Result::ConnectionID)
|
||||
}),
|
||||
SysCall::ReturnMemory(sender, buf, offset, valid) => return_memory(pid, tid, in_irq, sender, buf, offset, valid),
|
||||
SysCall::ReturnMemory(sender, buf, offset, valid) => {
|
||||
return_memory(pid, tid, in_irq, sender, buf, offset, valid)
|
||||
}
|
||||
SysCall::ReturnScalar1(sender, arg) => return_scalar(pid, tid, in_irq, sender, arg),
|
||||
SysCall::ReturnScalar2(sender, arg1, arg2) => {
|
||||
return_scalar2(pid, tid, in_irq, sender, arg1, arg2)
|
||||
|
|
@ -834,6 +840,10 @@ pub fn handle_inner(pid: PID, tid: TID, in_irq: bool, call: SysCall) -> SysCallR
|
|||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
SysCall::Disconnect(cid) => SystemServices::with_mut(|ss| {
|
||||
ss.disconnect_from_server(cid)
|
||||
.and(Ok(xous_kernel::Result::Ok))
|
||||
}),
|
||||
_ => Err(xous_kernel::Error::UnhandledSyscall),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue