      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
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262

    use std::cell::RefCell;
    use std::mem;
    use std::rc::Rc;
    use std::sync::atomic::Ordering;
    use std::sync::Arc;
    use std::thread;

    use {spawn_unsafe, FnBox};
    use sync::AtomicOption;

    pub struct Scope<'a> {
        dtors: RefCell<Option<DtorChain<'a>>>
    }

    struct DtorChain<'a> {
        dtor: Box<FnBox + 'a>,
        next: Option<Box<DtorChain<'a>>>
    }

    enum JoinState {
        Running(thread::JoinHandle<()>),
        Joined,
    }

    impl JoinState {
        fn join(&mut self) {
            let mut state = JoinState::Joined;
            mem::swap(self, &mut state);
            if let JoinState::Running(handle) = state {
                let res = handle.join();

                if !thread::panicking() { res.unwrap(); }
            }
        }
    }

    /// A handle to a scoped thread
    pub struct ScopedJoinHandle<T> {
        inner: Rc<RefCell<JoinState>>,
        packet: Arc<AtomicOption<T>>,
        thread: thread::Thread,
    }

    /// Create a new `scope`, for deferred destructors.
    ///
    /// Scopes, in particular, support [*scoped thread spawning*](struct.Scope.html#method.spawn).
    ///
    /// # Examples
    ///
    /// Creating and using a scope:
    ///
    /// ```
    /// crossbeam::scope(|scope| {
    ///     scope.defer(|| println!("Exiting scope"));
    ///     scope.spawn(|| println!("Running child thread in scope"))
    /// });
    /// // Prints messages in the reverse order written
    /// ```
    pub fn scope<'a, F, R>(f: F) -> R where F: FnOnce(&Scope<'a>) -> R {
        let mut scope = Scope { dtors: RefCell::new(None) };
        let ret = f(&scope);
        scope.drop_all();
        ret
    }

    impl<'a> Scope<'a> {
        // This method is carefully written in a transactional style, so
        // that it can be called directly and, if any dtor panics, can be
        // resumed in the unwinding this causes. By initially running the
        // method outside of any destructor, we avoid any leakage problems
        // due to @rust-lang/rust#14875.
        fn drop_all(&mut self) {
            loop {
                // use a separate scope to ensure that the RefCell borrow
                // is relinquishe before running `dtor`
                let dtor = {
                    let mut dtors = self.dtors.borrow_mut();
                    if let Some(mut node) = dtors.take() {
                        *dtors = node.next.take().map(|b| *b);
                        node.dtor
                    } else {
                        return
                    }
                };
                dtor.call_box()
            }
        }

        /// Schedule code to be executed when exiting the scope.
        ///
        /// This is akin to having a destructor on the stack, except that it is
        /// *guaranteed* to be run.
        pub fn defer<F>(&self, f: F) where F: FnOnce() + 'a {
            let mut dtors = self.dtors.borrow_mut();
            *dtors = Some(DtorChain {
                dtor: Box::new(f),
                next: dtors.take().map(Box::new)
            });
        }

        /// Create a scoped thread.
        ///
        /// `spawn` is similar to the [`spawn`][spawn] function in Rust's standard library. The
        /// difference is that this thread is scoped, meaning that it's guaranteed to terminate
        /// before the current stack frame goes away, allowing you to reference the parent stack frame
        /// directly. This is ensured by having the parent thread join on the child thread before the
        /// scope exits.
        ///
        /// [spawn]: http://doc.rust-lang.org/std/thread/fn.spawn.html
        ///
        /// # Examples
        ///
        /// A basic scoped thread:
        ///
        /// ```
        /// crossbeam::scope(|scope| {
        ///     scope.spawn(|| {
        ///         println!("Hello from a scoped thread!");
        ///     });
        /// });
        /// ```
        ///
        /// When writing concurrent Rust programs, you'll sometimes see a pattern like this, using
        /// [`std::thread::spawn`][spawn]:
        ///
        /// ```ignore
        /// let array = [1, 2, 3];
        /// let mut guards = vec![];
        ///
        /// for i in &array {
        ///     let guard = std::thread::spawn(move || {
        ///         println!("element: {}", i);
        ///     });
        ///
        ///     guards.push(guard);
        /// }
        ///
        /// for guard in guards {
        ///     guard.join().unwrap();
        /// }
        /// ```
        ///
        /// The basic pattern is:
        ///
        /// 1. Iterate over some collection.
        /// 2. Spin up a thread to operate on each part of the collection.
        /// 3. Join all the threads.
        ///
        /// However, this code actually gives an error:
        ///
        /// ```text
        /// error: `array` does not live long enough
        /// for i in &array {
        ///           ^~~~~
        /// in expansion of for loop expansion
        /// note: expansion site
        /// note: reference must be valid for the static lifetime...
        /// note: ...but borrowed value is only valid for the block suffix following statement 0 at ...
        ///     let array = [1, 2, 3];
        ///     let mut guards = vec![];
        ///
        ///     for i in &array {
        ///         let guard = std::thread::spawn(move || {
        ///             println!("element: {}", i);
        /// ...
        /// error: aborting due to previous error
        /// ```
        ///
        /// Because [`std::thread::spawn`][spawn] doesn't know about this scope, it requires a
        /// `'static` lifetime. One way of giving it a proper lifetime is to use an [`Arc`][arc]:
        ///
        /// [arc]: http://doc.rust-lang.org/stable/std/sync/struct.Arc.html
        ///
        /// ```
        /// use std::sync::Arc;
        ///
        /// let array = Arc::new([1, 2, 3]);
        /// let mut guards = vec![];
        ///
        /// for i in (0..array.len()) {
        ///     let a = array.clone();
        ///
        ///     let guard = std::thread::spawn(move || {
        ///         println!("element: {}", a[i]);
        ///     });
        ///
        ///     guards.push(guard);
        /// }
        ///
        /// for guard in guards {
        ///     guard.join().unwrap();
        /// }
        /// ```
        ///
        /// But this introduces unnecessary allocation, as `Arc<T>` puts its data on the heap, and we
        /// also end up dealing with reference counts. We know that we're joining the threads before
        /// our function returns, so just taking a reference _should_ be safe. Rust can't know that,
        /// though.
        ///
        /// Enter scoped threads. Here's our original example, using `spawn` from crossbeam rather
        /// than from `std::thread`:
        ///
        /// ```
        /// let array = [1, 2, 3];
        ///
        /// crossbeam::scope(|scope| {
        ///     for i in &array {
        ///         scope.spawn(move || {
        ///             println!("element: {}", i);
        ///         });
        ///     }
        /// });
        /// ```
        ///
        /// Much more straightforward.
        pub fn spawn<F, T>(&self, f: F) -> ScopedJoinHandle<T> where
            F: FnOnce() -> T + Send + 'a, T: Send + 'a
        {
            let their_packet = Arc::new(AtomicOption::new());
            let my_packet = their_packet.clone();

            let join_handle = unsafe {
                spawn_unsafe(move || {
                    their_packet.swap(f(), Ordering::Relaxed);
                })
            };

            let thread = join_handle.thread().clone();
            let deferred_handle = Rc::new(RefCell::new(JoinState::Running(join_handle)));
            let my_handle = deferred_handle.clone();

            self.defer(move || {
                let mut state = deferred_handle.borrow_mut();
                state.join();
            });

            ScopedJoinHandle {
                inner: my_handle,
                packet: my_packet,
                thread: thread,
            }
        }
    }

    impl<T> ScopedJoinHandle<T> {
        /// Join the scoped thread, returning the result it produced.
        pub fn join(self) -> T {
            self.inner.borrow_mut().join();
            self.packet.take(Ordering::Relaxed).unwrap()
        }

        /// Get the underlying thread handle.
        pub fn thread(&self) -> &thread::Thread {
            &self.thread
        }
    }

    impl<'a> Drop for Scope<'a> {
        fn drop(&mut self) {
            self.drop_all()
        }
    }

# Help

## Keyboard Shortcuts

?
  Show this help dialog
S
  Focus the search field
⇤
  Move up in search results
⇥
  Move down in search results
⏎
  Go to active search result

## 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`)