task.rs.html -- source
Description: Source to the Rust file `liballoc/task.rs`.
Keywords: rust, rustlang, rust-lang

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140

    // Copyright 2018 The Rust Project Developers. See the COPYRIGHT
    // file at the top-level directory of this distribution and at
    // http://rust-lang.org/COPYRIGHT.
    //
    // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
    // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
    // option. This file may not be copied, modified, or distributed
    // except according to those terms.

    //! Types and Traits for working with asynchronous tasks.

    pub use core::task::*;

    #[cfg(all(target_has_atomic = "ptr", target_has_atomic = "cas"))]
    pub use self::if_arc::*;

    #[cfg(all(target_has_atomic = "ptr", target_has_atomic = "cas"))]
    mod if_arc {
        use super::*;
        use core::marker::PhantomData;
        use core::mem;
        use core::ptr::{self, NonNull};
        use sync::Arc;

        /// A way of waking up a specific task.
        ///
        /// Any task executor must provide a way of signaling that a task it owns
        /// is ready to be `poll`ed again. Executors do so by implementing this trait.
        pub trait Wake: Send + Sync {
            /// Indicates that the associated task is ready to make progress and should
            /// be `poll`ed.
            ///
            /// Executors generally maintain a queue of "ready" tasks; `wake` should place
            /// the associated task onto this queue.
            fn wake(arc_self: &Arc<Self>);

            /// Indicates that the associated task is ready to make progress and should
            /// be `poll`ed. This function is like `wake`, but can only be called from the
            /// thread on which this `Wake` was created.
            ///
            /// Executors generally maintain a queue of "ready" tasks; `wake_local` should place
            /// the associated task onto this queue.
            #[inline]
            unsafe fn wake_local(arc_self: &Arc<Self>) {
                Self::wake(arc_self);
            }
        }

        #[cfg(all(target_has_atomic = "ptr", target_has_atomic = "cas"))]
        struct ArcWrapped<T>(PhantomData<T>);

        unsafe impl<T: Wake + 'static> UnsafeWake for ArcWrapped<T> {
            #[inline]
            unsafe fn clone_raw(&self) -> Waker {
                let me: *const ArcWrapped<T> = self;
                let arc = (*(&me as *const *const ArcWrapped<T> as *const Arc<T>)).clone();
                Waker::from(arc)
            }

            #[inline]
            unsafe fn drop_raw(&self) {
                let mut me: *const ArcWrapped<T> = self;
                let me = &mut me as *mut *const ArcWrapped<T> as *mut Arc<T>;
                ptr::drop_in_place(me);
            }

            #[inline]
            unsafe fn wake(&self) {
                let me: *const ArcWrapped<T> = self;
                T::wake(&*(&me as *const *const ArcWrapped<T> as *const Arc<T>))
            }

            #[inline]
            unsafe fn wake_local(&self) {
                let me: *const ArcWrapped<T> = self;
                T::wake_local(&*(&me as *const *const ArcWrapped<T> as *const Arc<T>))
            }
        }

        impl<T> From<Arc<T>> for Waker
            where T: Wake + 'static,
        {
            fn from(rc: Arc<T>) -> Self {
                unsafe {
                    let ptr = mem::transmute::<Arc<T>, NonNull<ArcWrapped<T>>>(rc);
                    Waker::new(ptr)
                }
            }
        }

        /// Creates a `LocalWaker` from a local `wake`.
        ///
        /// This function requires that `wake` is "local" (created on the current thread).
        /// The resulting `LocalWaker` will call `wake.wake_local()` when awoken, and
        /// will call `wake.wake()` if awoken after being converted to a `Waker`.
        #[inline]
        pub unsafe fn local_waker<W: Wake + 'static>(wake: Arc<W>) -> LocalWaker {
            let ptr = mem::transmute::<Arc<W>, NonNull<ArcWrapped<W>>>(wake);
            LocalWaker::new(ptr)
        }

        struct NonLocalAsLocal<T>(ArcWrapped<T>);

        unsafe impl<T: Wake + 'static> UnsafeWake for NonLocalAsLocal<T> {
            #[inline]
            unsafe fn clone_raw(&self) -> Waker {
                self.0.clone_raw()
            }

            #[inline]
            unsafe fn drop_raw(&self) {
                self.0.drop_raw()
            }

            #[inline]
            unsafe fn wake(&self) {
                self.0.wake()
            }

            #[inline]
            unsafe fn wake_local(&self) {
                // Since we're nonlocal, we can't call wake_local
                self.0.wake()
            }
        }

        /// Creates a `LocalWaker` from a non-local `wake`.
        ///
        /// This function is similar to `local_waker`, but does not require that `wake`
        /// is local to the current thread. The resulting `LocalWaker` will call
        /// `wake.wake()` when awoken.
        #[inline]
        pub fn local_waker_from_nonlocal<W: Wake + 'static>(wake: Arc<W>) -> LocalWaker {
            unsafe {
                let ptr = mem::transmute::<Arc<W>, NonNull<NonLocalAsLocal<W>>>(wake);
                LocalWaker::new(ptr)
            }
        }
    }

# Help

## Keyboard Shortcuts

`?`
  Show this help dialog
`S`
  Focus the search field
`↑`
  Move up in search results
`↓`
  Move down in search results
`↹`
  Switch tab
`⏎`
  Go to active search result
`+`
  Expand all sections
`-`
  Collapse all sections

## Search Tricks

Prefix searches with a type followed by a colon (e.g. `fn:`) to restrict the search to a given type.

Accepted types are: `fn`, `mod`, `struct`, `enum`, `trait`, `type`, `macro`, and `const`.

Search functions by type signature (e.g. `vec -> usize` or `* -> vec`)

Search multiple things at once by splitting your query with comma (e.g. `str,u8` or `String,struct:Vec,test`)