New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Async/Await semantics #7
Comments
Something like this? in lib.rs: struct Dest<T> {
flag: AtomicBool,
dest: Option<T>,
}
impl<T> Dest<T> {
// whether the destination has been filled.
fn probe(&self) -> bool { self.counter.load(Relaxed) }
// fill the destination with a value.
fn fill(&mut self, val: T) {
self.dest = Some(val);
fence(SeqCst); // not sure what degree of synchronization is required here.
self.counter.store(true, Relaxed);
}
}
pub struct Task<'a, T: 'a> {
dest: Box<Dest<T>>,
finished: bool,
worker: &'a Worker,
}
impl<'a, T: 'a> Task<'a, T> {
// helper function so we can call it in Drop impl.
fn _await(&mut self) -> T {
// busy wait until we're done.
while !self.dest.counter.probe() {
unsafe { self.worker.run_next() }
}
self.finished = true;
self.dest.dest.take().unwrap();
}
// public interface consumes `self`, which is semantically correct.
pub fn await(self) -> T {
let mut s = self;
s._await();
}
}
impl<'a, T: 'a> Drop for Task<'a, T> {
// we need to wait for the task to finish before we deallocate the boxed memory.
// otherwise, the task will attempt to write into free'd memory.
fn drop(&mut self) {
if !self.finished {
let _ = self._await();
}
}
}
impl<'pool, 'scope> Spawner<'pool, 'scope> {
fn async<F, T>(&self, f: F) -> Task<T>
where F: 'scope + Send + FnOnce() -> T, T: 'scope + Send {
let mut task = Task {
dest: Box::new(Dest {
counter: AtomicBool::new(false),
dest: None,
});
worker: self.worker
};
// wrapper type for sending raw pointers.
let dest_ptr = SendPtr(&mut *task.dest as *mut _);
self.submit(move || {
unsafe { (*dest_ptr).fill(f()) }
});
}
} This would probably work pretty well, but it may be unexpected that tasks are force-joined when dropped. The worker busy-waiting pattern is becoming common enough that maybe a |
The distinction between |
not implementing |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This would be definitely be a nice-to-have.
The text was updated successfully, but these errors were encountered: