Skip to content

Commit

Permalink
object: move exceptionate into Task trait
Browse files Browse the repository at this point in the history
  • Loading branch information
wangrunji0408 committed Aug 13, 2020
1 parent 62bd8a5 commit 98c064d
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 88 deletions.
4 changes: 2 additions & 2 deletions zircon-loader/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ fn spawn(thread: Arc<Thread>) {
.await;
};
Exception::create(thread.clone(), ExceptionType::ThreadStarting, None)
.handle_with_exceptionates(false, Some(thread.proc().get_debug_exceptionate()), false)
.handle_with_exceptionates(false, Some(thread.proc().debug_exceptionate()), false)
.await;
loop {
let mut cx = thread.wait_for_run().await;
Expand Down Expand Up @@ -270,7 +270,7 @@ fn spawn(thread: Arc<Thread>) {
let end_exception = Exception::create(thread.clone(), ExceptionType::ThreadExiting, None);
let handled = thread
.proc()
.get_debug_exceptionate()
.debug_exceptionate()
.send_exception(&end_exception);
if let Ok(future) = handled {
thread.dying_run(future).await.ok();
Expand Down
2 changes: 1 addition & 1 deletion zircon-object/src/hypervisor/vcpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ define_count_helper!(Vcpu);

impl Vcpu {
pub fn new(guest: Arc<Guest>, entry: u64, thread: Arc<Thread>) -> ZxResult<Arc<Self>> {
if thread.get_flags().contains(ThreadFlag::VCPU) {
if thread.flags().contains(ThreadFlag::VCPU) {
return Err(ZxError::BAD_STATE);
}
let inner = Mutex::new(VcpuInner::new(entry, guest.rvm_guest())?);
Expand Down
54 changes: 27 additions & 27 deletions zircon-object/src/task/exception.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,20 +475,20 @@ impl<'a> Iterator for ExceptionateIterator<'a> {
} else {
ExceptionateIteratorState::Thread
};
return Some(proc.get_debug_exceptionate());
return Some(proc.debug_exceptionate());
}
ExceptionateIteratorState::Thread => {
self.state = ExceptionateIteratorState::Process;
return Some(self.exception.thread.get_exceptionate());
return Some(self.exception.thread.exceptionate());
}
ExceptionateIteratorState::Process => {
let proc = self.exception.thread.proc();
self.state = ExceptionateIteratorState::Debug(true);
return Some(proc.get_exceptionate());
return Some(proc.exceptionate());
}
ExceptionateIteratorState::Job(job) => {
let parent = job.parent();
let result = job.get_exceptionate();
let result = job.exceptionate();
self.state = parent.map_or(
ExceptionateIteratorState::Finished,
ExceptionateIteratorState::Job,
Expand Down Expand Up @@ -516,7 +516,7 @@ impl JobDebuggerIterator {
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());
let result = self.job.as_ref().map(|job| job.debug_exceptionate());
self.job = self.job.as_ref().and_then(|job| job.parent());
result
}
Expand All @@ -536,11 +536,11 @@ mod tests {
let exception = Exception::create(thread.clone(), ExceptionType::Synth, None);
let iterator = ExceptionateIterator::new(&exception);
let expected = [
proc.get_debug_exceptionate(),
thread.get_exceptionate(),
proc.get_exceptionate(),
job.get_exceptionate(),
parent_job.get_exceptionate(),
proc.debug_exceptionate(),
thread.exceptionate(),
proc.exceptionate(),
job.exceptionate(),
parent_job.exceptionate(),
];
for (actual, expected) in iterator.zip(expected.iter()) {
assert!(Arc::ptr_eq(&actual, expected));
Expand All @@ -558,12 +558,12 @@ mod tests {
exception.inner.lock().second_chance = true;
let iterator = ExceptionateIterator::new(&exception);
let expected = [
proc.get_debug_exceptionate(),
thread.get_exceptionate(),
proc.get_exceptionate(),
proc.get_debug_exceptionate(),
job.get_exceptionate(),
parent_job.get_exceptionate(),
proc.debug_exceptionate(),
thread.exceptionate(),
proc.exceptionate(),
proc.debug_exceptionate(),
job.exceptionate(),
parent_job.exceptionate(),
];
for (actual, expected) in iterator.zip(expected.iter()) {
assert!(Arc::ptr_eq(&actual, expected));
Expand All @@ -579,9 +579,9 @@ mod tests {

let iterator = JobDebuggerIterator::new(child_job.clone());
let expected = [
child_job.get_debug_exceptionate(),
job.get_debug_exceptionate(),
parent_job.get_debug_exceptionate(),
child_job.debug_exceptionate(),
job.debug_exceptionate(),
parent_job.debug_exceptionate(),
];
for (actual, expected) in iterator.zip(expected.iter()) {
assert!(Arc::ptr_eq(&actual, expected));
Expand Down Expand Up @@ -639,22 +639,22 @@ mod tests {
};

// proc debug should get the exception first
create_handler(&proc.get_debug_exceptionate(), true, false, 0);
create_handler(&proc.debug_exceptionate(), true, false, 0);
// thread should get the exception next
create_handler(&thread.get_exceptionate(), true, false, 1);
create_handler(&thread.exceptionate(), true, false, 1);
// here we omit proc to test that we can handle the case that there is none handler
// job should get the exception and handle it next
create_handler(&job.get_exceptionate(), true, true, 3);
create_handler(&job.exceptionate(), true, true, 3);
// since exception is handled we should not get it from parent job
create_handler(&parent_job.get_exceptionate(), false, false, 4);
create_handler(&parent_job.exceptionate(), false, false, 4);

exception.handle(false).await;

// terminate handlers by shutdown the related exceptionates
thread.get_exceptionate().shutdown();
proc.get_debug_exceptionate().shutdown();
job.get_exceptionate().shutdown();
parent_job.get_exceptionate().shutdown();
thread.exceptionate().shutdown();
proc.debug_exceptionate().shutdown();
job.exceptionate().shutdown();
parent_job.exceptionate().shutdown();

// test for the order: proc debug -> thread -> job
assert_eq!(handled_order.lock().clone(), vec![0, 1, 3]);
Expand Down
46 changes: 27 additions & 19 deletions zircon-object/src/task/job.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,16 +198,6 @@ impl Job {
}
}

/// Get the exceptionate of this job.
pub fn get_exceptionate(&self) -> Arc<Exceptionate> {
self.exceptionate.clone()
}

/// Get the debug exceptionate of this job.
pub fn get_debug_exceptionate(&self) -> Arc<Exceptionate> {
self.debug_exceptionate.clone()
}

/// Get KoIDs of Processes.
pub fn process_ids(&self) -> Vec<KoID> {
self.inner.lock().processes.iter().map(|p| p.id()).collect()
Expand All @@ -229,9 +219,21 @@ impl Job {
self.inner.lock().is_empty()
}

/// The job finally terminates.
fn terminate(&self) {
self.exceptionate.shutdown();
self.debug_exceptionate.shutdown();
self.base.signal_set(Signal::JOB_TERMINATED);
if let Some(parent) = self.parent.as_ref() {
parent.remove_child(&self.inner.lock().self_ref)
}
}
}

impl Task for Job {
/// Kill the job. The job do not terminate immediately when killed.
/// It will terminate after all its children and processes are terminated.
pub fn kill(&self) {
fn kill(&self) {
let (children, processes) = {
let mut inner = self.inner.lock();
if inner.killed {
Expand All @@ -254,14 +256,20 @@ impl Job {
}
}

/// The job finally terminates.
fn terminate(&self) {
self.exceptionate.shutdown();
self.debug_exceptionate.shutdown();
self.base.signal_set(Signal::JOB_TERMINATED);
if let Some(parent) = self.parent.as_ref() {
parent.remove_child(&self.inner.lock().self_ref)
}
fn suspend(&self) {
panic!("job do not support suspend");
}

fn resume(&self) {
panic!("job do not support resume");
}

fn exceptionate(&self) -> Arc<Exceptionate> {
self.exceptionate.clone()
}

fn debug_exceptionate(&self) -> Arc<Exceptionate> {
self.debug_exceptionate.clone()
}
}

Expand Down
7 changes: 7 additions & 0 deletions zircon-object/src/task/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//! Objects for Task Management.
use super::*;
use alloc::sync::Arc;

mod exception;
mod job;
Expand All @@ -26,6 +27,12 @@ pub trait Task: Sync + Send {

/// Resume the task
fn resume(&self);

/// Get the exceptionate.
fn exceptionate(&self) -> Arc<Exceptionate>;

/// Get the debug exceptionate.
fn debug_exceptionate(&self) -> Arc<Exceptionate>;
}

/// The return code set when a task is killed via zx_task_kill().
Expand Down
18 changes: 8 additions & 10 deletions zircon-object/src/task/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,16 +492,6 @@ impl Process {
self.inner.lock().get_cancel_token(handle_value)
}

/// Get the exceptionate of this process.
pub fn get_exceptionate(&self) -> Arc<Exceptionate> {
self.exceptionate.clone()
}

/// Get the debug exceptionate of this process.
pub fn get_debug_exceptionate(&self) -> Arc<Exceptionate> {
self.debug_exceptionate.clone()
}

/// Get KoIDs of Threads.
pub fn thread_ids(&self) -> Vec<KoID> {
self.inner.lock().threads.iter().map(|t| t.id()).collect()
Expand All @@ -526,6 +516,14 @@ impl Task for Process {
thread.resume();
}
}

fn exceptionate(&self) -> Arc<Exceptionate> {
self.exceptionate.clone()
}

fn debug_exceptionate(&self) -> Arc<Exceptionate> {
self.debug_exceptionate.clone()
}
}

impl ProcessInner {
Expand Down
52 changes: 28 additions & 24 deletions zircon-object/src/task/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,30 +131,34 @@ struct ThreadInner {
}

impl ThreadInner {
pub fn get_state(&self) -> ThreadState {
fn get_state(&self) -> ThreadState {
if self.suspend_count == 0 || self.state == ThreadState::BlockedException {
self.state
} else {
ThreadState::Suspended
}
}

fn update_signal(&self, base: &KObjectBase) {
if self.state == ThreadState::Dead {
base.signal_clear(Signal::THREAD_RUNNING);
base.signal_clear(Signal::THREAD_SUSPENDED);
base.signal_set(Signal::THREAD_TERMINATED)
base.signal_change(
Signal::THREAD_RUNNING | Signal::THREAD_SUSPENDED,
Signal::THREAD_TERMINATED,
);
} else if self.state == ThreadState::New || self.state == ThreadState::Dying {
base.signal_clear(Signal::THREAD_RUNNING);
base.signal_clear(Signal::THREAD_SUSPENDED);
base.signal_clear(Signal::THREAD_TERMINATED)
base.signal_clear(
Signal::THREAD_RUNNING | Signal::THREAD_SUSPENDED | Signal::THREAD_TERMINATED,
);
} else if self.suspend_count == 0 || self.state == ThreadState::BlockedException {
base.signal_set(Signal::THREAD_RUNNING);
base.signal_clear(Signal::THREAD_SUSPENDED);
base.signal_clear(Signal::THREAD_TERMINATED)
base.signal_change(
Signal::THREAD_TERMINATED | Signal::THREAD_SUSPENDED,
Signal::THREAD_RUNNING,
);
} else {
base.signal_clear(Signal::THREAD_RUNNING);
base.signal_set(Signal::THREAD_SUSPENDED);
base.signal_clear(Signal::THREAD_TERMINATED)
base.signal_change(
Signal::THREAD_RUNNING | Signal::THREAD_TERMINATED,
Signal::THREAD_SUSPENDED,
);
}
}
}
Expand Down Expand Up @@ -476,11 +480,6 @@ impl Thread {
self.inner.lock().get_state()
}

/// Get the exceptionate.
pub fn get_exceptionate(&self) -> Arc<Exceptionate> {
self.exceptionate.clone()
}

/// Add the parameter to the time this thread has run on cpu.
pub fn time_add(&self, time: u128) {
self.inner.lock().time += time;
Expand All @@ -502,15 +501,12 @@ impl Thread {
}

/// Get the thread's flags.
pub fn get_flags(&self) -> ThreadFlag {
pub fn flags(&self) -> ThreadFlag {
self.inner.lock().flags
}

/// Apply `f` to the thread's flags.
pub fn update_flags<F>(&self, f: F)
where
F: FnOnce(&mut ThreadFlag),
{
pub fn update_flags(&self, f: impl FnOnce(&mut ThreadFlag)) {
f(&mut self.inner.lock().flags)
}
}
Expand Down Expand Up @@ -545,6 +541,14 @@ impl Task for Thread {
}
}
}

fn exceptionate(&self) -> Arc<Exceptionate> {
self.exceptionate.clone()
}

fn debug_exceptionate(&self) -> Arc<Exceptionate> {
panic!("thread do not have debug exceptionate");
}
}

/// `into_result` returns `Self` if the type parameter is already a `ZxResult`,
Expand Down Expand Up @@ -631,7 +635,7 @@ mod tests {
let root_job = Job::root();
let proc = Process::create(&root_job, "proc").expect("failed to create process");
let thread = Thread::create(&proc, "thread").expect("failed to create thread");
assert_eq!(thread.get_flags(), ThreadFlag::empty());
assert_eq!(thread.flags(), ThreadFlag::empty());

let thread: Arc<dyn KernelObject> = thread;
assert_eq!(thread.related_koid(), proc.id());
Expand Down
10 changes: 5 additions & 5 deletions zircon-syscall/src/exception.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,20 @@ impl Syscall<'_> {
return Err(ZxError::ACCESS_DENIED);
}
match option {
ExceptionChannelOption::None => job.get_exceptionate(),
ExceptionChannelOption::Debugger => job.get_debug_exceptionate(),
ExceptionChannelOption::None => job.exceptionate(),
ExceptionChannelOption::Debugger => job.debug_exceptionate(),
}
} else if let Ok(process) = task.clone().downcast_arc::<Process>() {
if !rights.contains(Rights::ENUMERATE) {
return Err(ZxError::ACCESS_DENIED);
}
match option {
ExceptionChannelOption::None => process.get_exceptionate(),
ExceptionChannelOption::Debugger => process.get_debug_exceptionate(),
ExceptionChannelOption::None => process.exceptionate(),
ExceptionChannelOption::Debugger => process.debug_exceptionate(),
}
} else if let Ok(thread) = task.clone().downcast_arc::<Thread>() {
match option {
ExceptionChannelOption::None => thread.get_exceptionate(),
ExceptionChannelOption::None => thread.exceptionate(),
ExceptionChannelOption::Debugger => return Err(ZxError::INVALID_ARGS),
}
} else {
Expand Down

0 comments on commit 98c064d

Please sign in to comment.