summaryrefslogtreecommitdiff
path: root/monoio/src/task/raw.rs
diff options
context:
space:
mode:
authorihciah <[email protected]>2021-12-02 14:38:25 +0800
committerihciah <[email protected]>2021-12-02 14:38:25 +0800
commit9df6a26f2f51aba824ceeee21179fbff4dd42d49 (patch)
tree031cacffb874f003a313d5fe6094751927efcdf0 /monoio/src/task/raw.rs
Init: open-source
Diffstat (limited to 'monoio/src/task/raw.rs')
-rw-r--r--monoio/src/task/raw.rs127
1 files changed, 127 insertions, 0 deletions
diff --git a/monoio/src/task/raw.rs b/monoio/src/task/raw.rs
new file mode 100644
index 0000000..1df0137
--- /dev/null
+++ b/monoio/src/task/raw.rs
@@ -0,0 +1,127 @@
+use crate::task::{Cell, Harness, Header, Schedule};
+
+use std::{
+ future::Future,
+ ptr::NonNull,
+ task::{Poll, Waker},
+};
+
+pub(crate) struct RawTask {
+ ptr: NonNull<Header>,
+}
+
+impl Clone for RawTask {
+ fn clone(&self) -> Self {
+ RawTask { ptr: self.ptr }
+ }
+}
+
+impl Copy for RawTask {}
+
+pub(crate) struct Vtable {
+ /// Poll the future
+ pub(crate) poll: unsafe fn(NonNull<Header>),
+ /// Deallocate the memory
+ pub(crate) dealloc: unsafe fn(NonNull<Header>),
+
+ /// Read the task output, if complete
+ pub(crate) try_read_output: unsafe fn(NonNull<Header>, *mut (), &Waker),
+
+ /// The join handle has been dropped
+ pub(crate) drop_join_handle_slow: unsafe fn(NonNull<Header>),
+}
+
+/// Get the vtable for the requested `T` and `S` generics.
+pub(super) fn vtable<T: Future, S: Schedule>() -> &'static Vtable {
+ &Vtable {
+ poll: poll::<T, S>,
+ dealloc: dealloc::<T, S>,
+ try_read_output: try_read_output::<T, S>,
+ drop_join_handle_slow: drop_join_handle_slow::<T, S>,
+ }
+}
+
+impl RawTask {
+ #[cfg(not(feature = "sync"))]
+ pub(crate) fn new<T, S>(task: T, scheduler: S) -> RawTask
+ where
+ T: Future,
+ S: Schedule,
+ {
+ let ptr = Box::into_raw(Cell::new(task, scheduler));
+ let ptr = unsafe { NonNull::new_unchecked(ptr as *mut Header) };
+
+ RawTask { ptr }
+ }
+
+ #[cfg(feature = "sync")]
+ pub(crate) fn new<T, S>(owner_id: usize, task: T, scheduler: S) -> RawTask
+ where
+ T: Future,
+ S: Schedule,
+ {
+ let ptr = Box::into_raw(Cell::new(owner_id, task, scheduler));
+ let ptr = unsafe { NonNull::new_unchecked(ptr as *mut Header) };
+
+ RawTask { ptr }
+ }
+
+ pub(crate) unsafe fn from_raw(ptr: NonNull<Header>) -> RawTask {
+ RawTask { ptr }
+ }
+
+ pub(crate) fn header(&self) -> &Header {
+ unsafe { self.ptr.as_ref() }
+ }
+
+ /// Safety: mutual exclusion is required to call this function.
+ pub(crate) fn poll(self) {
+ let vtable = self.header().vtable;
+ unsafe { (vtable.poll)(self.ptr) }
+ }
+
+ pub(crate) fn dealloc(self) {
+ let vtable = self.header().vtable;
+ unsafe {
+ (vtable.dealloc)(self.ptr);
+ }
+ }
+
+ /// Safety: `dst` must be a `*mut Poll<super::Result<T::Output>>` where `T`
+ /// is the future stored by the task.
+ pub(crate) unsafe fn try_read_output(self, dst: *mut (), waker: &Waker) {
+ let vtable = self.header().vtable;
+ (vtable.try_read_output)(self.ptr, dst, waker);
+ }
+
+ pub(crate) fn drop_join_handle_slow(self) {
+ let vtable = self.header().vtable;
+ unsafe { (vtable.drop_join_handle_slow)(self.ptr) }
+ }
+}
+
+unsafe fn poll<T: Future, S: Schedule>(ptr: NonNull<Header>) {
+ let harness = Harness::<T, S>::from_raw(ptr);
+ harness.poll();
+}
+
+unsafe fn dealloc<T: Future, S: Schedule>(ptr: NonNull<Header>) {
+ let harness = Harness::<T, S>::from_raw(ptr);
+ harness.dealloc();
+}
+
+unsafe fn try_read_output<T: Future, S: Schedule>(
+ ptr: NonNull<Header>,
+ dst: *mut (),
+ waker: &Waker,
+) {
+ let out = &mut *(dst as *mut Poll<T::Output>);
+
+ let harness = Harness::<T, S>::from_raw(ptr);
+ harness.try_read_output(out, waker);
+}
+
+unsafe fn drop_join_handle_slow<T: Future, S: Schedule>(ptr: NonNull<Header>) {
+ let harness = Harness::<T, S>::from_raw(ptr);
+ harness.drop_join_handle_slow()
+}