1 // Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 #![unstable(feature = "futures_api",
12 reason = "futures in libcore are unstable",
18 use super::{Context, Poll};
20 /// A custom trait object for polling tasks, roughly akin to
21 /// `Box<Future<Output = ()>>`.
22 /// Contrary to `TaskObj`, `LocalTaskObj` does not have a `Send` bound.
23 pub struct LocalTaskObj {
25 poll_fn: unsafe fn(*mut (), &mut Context) -> Poll<()>,
26 drop_fn: unsafe fn(*mut ()),
30 /// Create a `LocalTaskObj` from a custom trait object representation.
32 pub fn new<T: UnsafeTask>(t: T) -> LocalTaskObj {
40 /// Converts the `LocalTaskObj` into a `TaskObj`
41 /// To make this operation safe one has to ensure that the `UnsafeTask`
42 /// instance from which this `LocalTaskObj` was created actually implements
44 pub unsafe fn as_task_obj(self) -> TaskObj {
49 impl fmt::Debug for LocalTaskObj {
50 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51 f.debug_struct("LocalTaskObj")
56 impl From<TaskObj> for LocalTaskObj {
57 fn from(task: TaskObj) -> LocalTaskObj {
62 impl Future for LocalTaskObj {
66 fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<()> {
68 (self.poll_fn)(self.ptr, cx)
73 impl Drop for LocalTaskObj {
76 (self.drop_fn)(self.ptr)
81 /// A custom trait object for polling tasks, roughly akin to
82 /// `Box<Future<Output = ()> + Send>`.
83 pub struct TaskObj(LocalTaskObj);
85 unsafe impl Send for TaskObj {}
88 /// Create a `TaskObj` from a custom trait object representation.
90 pub fn new<T: UnsafeTask + Send>(t: T) -> TaskObj {
91 TaskObj(LocalTaskObj::new(t))
95 impl fmt::Debug for TaskObj {
96 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
97 f.debug_struct("TaskObj")
102 impl Future for TaskObj {
106 fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<()> {
107 let pinned_field = unsafe { PinMut::map_unchecked(self, |x| &mut x.0) };
108 pinned_field.poll(cx)
112 /// A custom implementation of a task trait object for `TaskObj`, providing
113 /// a hand-rolled vtable.
115 /// This custom representation is typically used only in `no_std` contexts,
116 /// where the default `Box`-based implementation is not available.
118 /// The implementor must guarantee that it is safe to call `poll` repeatedly (in
119 /// a non-concurrent fashion) with the result of `into_raw` until `drop` is
121 pub unsafe trait UnsafeTask: 'static {
122 /// Convert a owned instance into a (conceptually owned) void pointer.
123 fn into_raw(self) -> *mut ();
125 /// Poll the task represented by the given void pointer.
129 /// The trait implementor must guarantee that it is safe to repeatedly call
130 /// `poll` with the result of `into_raw` until `drop` is called; such calls
131 /// are not, however, allowed to race with each other or with calls to `drop`.
132 unsafe fn poll(task: *mut (), cx: &mut Context) -> Poll<()>;
134 /// Drops the task represented by the given void pointer.
138 /// The trait implementor must guarantee that it is safe to call this
139 /// function once per `into_raw` invocation; that call cannot race with
140 /// other calls to `drop` or `poll`.
141 unsafe fn drop(task: *mut ());