forked from rcore-os/zCore
ProcessStarting exception
This commit is contained in:
parent
24f5a4bbf0
commit
641181bdb8
|
@ -172,13 +172,19 @@ kcounter!(EXCEPTIONS_USER, "exceptions.user");
|
|||
kcounter!(EXCEPTIONS_TIMER, "exceptions.timer");
|
||||
kcounter!(EXCEPTIONS_PGFAULT, "exceptions.pgfault");
|
||||
|
||||
fn spawn(thread: Arc<Thread>) {
|
||||
fn spawn(thread: Arc<Thread>,first_thread:bool) {
|
||||
let vmtoken = thread.proc().vmar().table_phys();
|
||||
let future = async move {
|
||||
kernel_hal::Thread::set_tid(thread.id(), thread.proc().id());
|
||||
let mut exit=false;
|
||||
if first_thread {
|
||||
let proc_start_exception=Exception::create(thread.clone(), ExceptionType::ProcessStarting,None);
|
||||
if !proc_start_exception.handle_with_exceptionates(false,JobDebuggerIterator::new(thread.proc().job()),true).await{
|
||||
exit=true;
|
||||
}
|
||||
};
|
||||
let start_exception=Exception::create(thread.clone(), ExceptionType::ThreadStarting,None);
|
||||
if !start_exception.handle_with_exceptionates(false,Some(thread.proc().get_debug_exceptionate())).await {
|
||||
if !start_exception.handle_with_exceptionates(false,Some(thread.proc().get_debug_exceptionate()),false).await {
|
||||
exit=true;
|
||||
}
|
||||
while !exit {
|
||||
|
|
|
@ -252,13 +252,15 @@ impl Exception {
|
|||
/// Note that it's possible that this may returns before exception was send to any exception channel
|
||||
/// This happens only when the thread is killed before we send the exception
|
||||
pub async fn handle(self: &Arc<Self>,fatal:bool) -> bool {
|
||||
self.handle_with_exceptionates(fatal,ExceptionateIterator::new(self)).await
|
||||
self.handle_with_exceptionates(fatal,ExceptionateIterator::new(self),false).await
|
||||
}
|
||||
|
||||
/// Same as handle, but use a customed iterator
|
||||
pub async fn handle_with_exceptionates(self: &Arc<Self>,fatal:bool,exceptionates:impl IntoIterator<Item=Arc<Exceptionate>>) -> bool {
|
||||
/// If first_only is true, this will only send exception to the first one that recieved the exception
|
||||
/// even when the exception is not handled
|
||||
pub async fn handle_with_exceptionates(self: &Arc<Self>,fatal:bool,exceptionates:impl IntoIterator<Item=Arc<Exceptionate>>,first_only:bool) -> bool {
|
||||
self.thread.set_exception(Some(self.clone()));
|
||||
let future = self.handle_internal(exceptionates);
|
||||
let future = self.handle_internal(exceptionates,first_only);
|
||||
pin_mut!(future);
|
||||
let result: ZxResult = self
|
||||
.thread
|
||||
|
@ -288,7 +290,7 @@ impl Exception {
|
|||
true
|
||||
}
|
||||
|
||||
async fn handle_internal(self: &Arc<Self>,exceptionates:impl IntoIterator<Item=Arc<Exceptionate>>) -> ZxResult {
|
||||
async fn handle_internal(self: &Arc<Self>,exceptionates:impl IntoIterator<Item=Arc<Exceptionate>>,first_only:bool) -> ZxResult {
|
||||
for exceptionate in exceptionates.into_iter() {
|
||||
let closed = match exceptionate.send_exception(self) {
|
||||
Ok(receiver) => receiver,
|
||||
|
@ -304,7 +306,7 @@ impl Exception {
|
|||
inner.current_channel_type = ExceptionChannelType::None;
|
||||
inner.handled
|
||||
};
|
||||
if handled {
|
||||
if handled | first_only {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
@ -431,3 +433,23 @@ impl<'a> Iterator for ExceptionateIterator<'a> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This is only used by ProcessStarting exceptions
|
||||
pub struct JobDebuggerIterator {
|
||||
job: Option<Arc<Job>>
|
||||
}
|
||||
|
||||
impl JobDebuggerIterator {
|
||||
pub fn new(job: Arc<Job>)->Self {
|
||||
JobDebuggerIterator{job:Some(job)}
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for JobDebuggerIterator {
|
||||
type Item = Arc<Exceptionate>;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let result=self.job.as_ref().map(|job|job.get_debug_exceptionate());
|
||||
self.job=self.job.as_ref().and_then(|job|job.parent());
|
||||
result
|
||||
}
|
||||
}
|
|
@ -141,7 +141,7 @@ impl Process {
|
|||
stack: usize,
|
||||
arg1: Option<Handle>,
|
||||
arg2: usize,
|
||||
spawn_fn: fn(thread: Arc<Thread>),
|
||||
spawn_fn: fn(thread: Arc<Thread>,bool),
|
||||
) -> ZxResult {
|
||||
let handle_value;
|
||||
{
|
||||
|
@ -155,7 +155,7 @@ impl Process {
|
|||
inner.status = Status::Running;
|
||||
handle_value = arg1.map_or(INVALID_HANDLE, |handle| inner.add_handle(handle));
|
||||
}
|
||||
match thread.start(entry, stack, handle_value as usize, arg2, spawn_fn) {
|
||||
match thread.start(entry, stack, handle_value as usize, arg2, spawn_fn,true) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(err) => {
|
||||
let mut inner = self.inner.lock();
|
||||
|
|
|
@ -179,7 +179,8 @@ impl Thread {
|
|||
stack: usize,
|
||||
arg1: usize,
|
||||
arg2: usize,
|
||||
spawn_fn: fn(thread: Arc<Thread>),
|
||||
spawn_fn: fn(thread: Arc<Thread>,bool),
|
||||
first_thread: bool
|
||||
) -> ZxResult {
|
||||
{
|
||||
let mut inner = self.inner.lock();
|
||||
|
@ -202,7 +203,7 @@ impl Thread {
|
|||
inner.state = ThreadState::Running;
|
||||
self.base.signal_set(Signal::THREAD_RUNNING);
|
||||
}
|
||||
spawn_fn(self.clone());
|
||||
spawn_fn(self.clone(),first_thread);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ use consts::SyscallType as Sys;
|
|||
pub struct Syscall<'a> {
|
||||
pub regs: &'a mut GeneralRegs,
|
||||
pub thread: Arc<Thread>,
|
||||
pub spawn_fn: fn(thread: Arc<Thread>),
|
||||
pub spawn_fn: fn(thread: Arc<Thread>,first_thread:bool),
|
||||
pub exit: bool,
|
||||
}
|
||||
|
||||
|
|
|
@ -153,7 +153,7 @@ impl Syscall<'_> {
|
|||
if thread.proc().status() != Status::Running {
|
||||
return Err(ZxError::BAD_STATE);
|
||||
}
|
||||
thread.start(entry, stack, arg1, arg2, self.spawn_fn)?;
|
||||
thread.start(entry, stack, arg1, arg2, self.spawn_fn,false)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue