-
-
Notifications
You must be signed in to change notification settings - Fork 102
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b825af1
commit 1ea3cb9
Showing
9 changed files
with
183 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
use bastion_executor::prelude::*; | ||
use lightproc::proc_stack::ProcStack; | ||
use std::{thread, time}; | ||
|
||
fn main() { | ||
run( | ||
async { | ||
println!("DATA"); | ||
panic!("kaka"); | ||
}, | ||
ProcStack::default() | ||
.with_after_panic(|| {println!("after panic")}), | ||
); | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
use bastion_executor::prelude::*; | ||
use lightproc::proc_stack::ProcStack; | ||
use std::{thread, time}; | ||
|
||
const SIXTY_MILLIS: time::Duration = time::Duration::from_millis(4000); | ||
|
||
fn main() { | ||
let stack = ProcStack::default() | ||
.with_pid(1) | ||
.with_after_panic(|| {println!("after panic")}); | ||
|
||
let handle = spawn(async { | ||
panic!("test"); | ||
}, stack); | ||
|
||
let stack = ProcStack::default() | ||
.with_pid(2) | ||
.with_after_panic(|| {println!("after panic")}); | ||
|
||
run( | ||
async { | ||
handle.await | ||
}, | ||
stack.clone() | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
use std::future::Future; | ||
use std::cell::UnsafeCell; | ||
use std::cell::Cell; | ||
use std::pin::Pin; | ||
use std::{mem, panic}; | ||
use lightproc::proc_stack::ProcStack; | ||
use super::worker; | ||
use std::sync::Arc; | ||
use crossbeam_utils::sync::Parker; | ||
use std::mem::ManuallyDrop; | ||
use std::task::{Waker, RawWaker, Context, Poll, RawWakerVTable}; | ||
use pin_utils::*; | ||
|
||
pub fn run<F, T>(future: F, stack: ProcStack) -> T | ||
where | ||
F: Future<Output = T>, | ||
{ | ||
unsafe { | ||
// A place on the stack where the result will be stored. | ||
let out = &mut UnsafeCell::new(None); | ||
|
||
// Wrap the future into one that stores the result into `out`. | ||
let future = { | ||
let out = out.get(); | ||
|
||
async move { | ||
*out = Some(future.await); | ||
} | ||
}; | ||
|
||
// Log this `block_on` operation. | ||
let child_id = stack.get_pid(); | ||
let parent_id = worker::get_proc_stack(|t| t.get_pid()).unwrap_or(0); | ||
|
||
// Wrap the future into one that drops task-local variables on exit. | ||
// let future = task_local::add_finalizer(future); | ||
|
||
let future = async move { | ||
future.await; | ||
}; | ||
|
||
// Pin the future onto the stack. | ||
pin_utils::pin_mut!(future); | ||
|
||
// Transmute the future into one that is futurestatic. | ||
let future = mem::transmute::< | ||
Pin<&'_ mut dyn Future<Output = ()>>, | ||
Pin<&'static mut dyn Future<Output = ()>>, | ||
>(future); | ||
|
||
// Block on the future and and wait for it to complete. | ||
worker::set_stack(&stack, || block(future)); | ||
|
||
// Take out the result. | ||
match (*out.get()).take() { | ||
Some(v) => v, | ||
_ => unimplemented!(), | ||
} | ||
} | ||
} | ||
|
||
|
||
|
||
fn block<F, T>(f: F) -> T | ||
where | ||
F: Future<Output = T>, | ||
{ | ||
thread_local! { | ||
// May hold a pre-allocated parker that can be reused for efficiency. | ||
// | ||
// Note that each invocation of `block` needs its own parker. In particular, if `block` | ||
// recursively calls itself, we must make sure that each recursive call uses a distinct | ||
// parker instance. | ||
static CACHE: Cell<Option<Arc<Parker>>> = Cell::new(None); | ||
} | ||
|
||
pin_utils::pin_mut!(f); | ||
|
||
CACHE.with(|cache| { | ||
// Reuse a cached parker or create a new one for this invocation of `block`. | ||
let arc_parker: Arc<Parker> = cache.take().unwrap_or_else(|| Arc::new(Parker::new())); | ||
|
||
let ptr = (&*arc_parker as *const Parker) as *const (); | ||
let vt = vtable(); | ||
|
||
let waker = unsafe { ManuallyDrop::new(Waker::from_raw(RawWaker::new(ptr, vt))) }; | ||
let cx = &mut Context::from_waker(&waker); | ||
|
||
loop { | ||
if let Poll::Ready(t) = f.as_mut().poll(cx) { | ||
// Save the parker for the next invocation of `block`. | ||
cache.set(Some(arc_parker)); | ||
return t; | ||
} | ||
arc_parker.park(); | ||
} | ||
}) | ||
} | ||
|
||
fn vtable() -> &'static RawWakerVTable { | ||
unsafe fn clone_raw(ptr: *const ()) -> RawWaker { | ||
#![allow(clippy::redundant_clone)] | ||
let arc = ManuallyDrop::new(Arc::from_raw(ptr as *const Parker)); | ||
mem::forget(arc.clone()); | ||
RawWaker::new(ptr, vtable()) | ||
} | ||
|
||
unsafe fn wake_raw(ptr: *const ()) { | ||
let arc = Arc::from_raw(ptr as *const Parker); | ||
arc.unparker().unpark(); | ||
} | ||
|
||
unsafe fn wake_by_ref_raw(ptr: *const ()) { | ||
let arc = ManuallyDrop::new(Arc::from_raw(ptr as *const Parker)); | ||
arc.unparker().unpark(); | ||
} | ||
|
||
unsafe fn drop_raw(ptr: *const ()) { | ||
drop(Arc::from_raw(ptr as *const Parker)) | ||
} | ||
|
||
&RawWakerVTable::new(clone_raw, wake_raw, wake_by_ref_raw, drop_raw) | ||
} |