This repository has been archived by the owner. It is now read-only.

Fix a few lifetime issues #36

Merged
merged 1 commit into from Jul 27, 2018

Conversation

Projects
None yet
2 participants
@stjepang
Copy link
Member

stjepang commented Jul 26, 2018

More safety problems getting fixed... :)

Explanation below in comments.

@@ -183,7 +183,7 @@ struct JoinState<T> {
_marker: PhantomData<T>,
}

impl<T: Send> JoinState<T> {
impl<T> JoinState<T> {

This comment has been minimized.

@stjepang

stjepang Jul 26, 2018

Member

We don't really need this bound because JoinState cannot be created unless T: Send. Note that JoinHandle doesn't have this impl bound either.

@@ -226,7 +229,7 @@ pub struct ScopedJoinHandle<'a, T: 'a> {
/// ```
/// crossbeam_utils::thread::scope(|scope| {
/// scope.defer(|| println!("Exiting scope"));
/// scope.spawn(|| println!("Running child thread in scope"))
/// scope.spawn(|| println!("Running child thread in scope"));

This comment has been minimized.

@stjepang

stjepang Jul 26, 2018

Member

Without the semicolon the ScopedJoinHandle was actually returned by the invocation of scope(), thus leaking out of the scope!

@@ -299,7 +302,7 @@ impl<'a> Scope<'a> {
/// scope exits.
///
/// [spawn]: http://doc.rust-lang.org/std/thread/fn.spawn.html
pub fn spawn<F, T>(&self, f: F) -> ScopedJoinHandle<'a, T>
pub fn spawn<'s, F, T>(&'s self, f: F) -> ScopedJoinHandle<'s, T>

This comment has been minimized.

@stjepang

stjepang Jul 26, 2018

Member

ScopedJoinHandle must borrow the Scope (lifetime 's), not the environment outside the scope (lifetime 'a).

Previously the following was compiling just fine:

let m = Mutex::new(None);
scope(|s| {
    let h = s.spawn(|| ());
    *m.lock().unwrap() = Some(h);
});
@@ -340,7 +343,7 @@ impl<'s, 'a: 's> ScopedThreadBuilder<'s, 'a> {
}

/// Spawns a new thread, and returns a join handle for it.
pub fn spawn<F, T>(self, f: F) -> io::Result<ScopedJoinHandle<'a, T>>
pub fn spawn<F, T>(self, f: F) -> io::Result<ScopedJoinHandle<'s, T>>

This comment has been minimized.

@stjepang

stjepang Jul 26, 2018

Member

Same as above.

@stjepang

This comment has been minimized.

Copy link
Member

stjepang commented Jul 26, 2018

One more thing: we should really choose better names for lifetimes 'a and 's. I suggest 'env (as in "environment" - borrows variables outside the scope) and 'scope (as in "Scope" - borrows the actual scope).

Thoughts?

@@ -208,6 +208,9 @@ pub struct ScopedJoinHandle<'a, T: 'a> {
_marker: PhantomData<&'a T>,
}

unsafe impl<'a, T> Send for ScopedJoinHandle<'a, T> {}
unsafe impl<'a, T> Sync for ScopedJoinHandle<'a, T> {}

This comment has been minimized.

@stjepang

stjepang Jul 26, 2018

Member

I've also submitted a PR that adds similar impls for JoinHandle:
rust-lang/rust#52759

@stjepang stjepang merged commit 95c3e2e into crossbeam-rs:master Jul 27, 2018

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details

@stjepang stjepang deleted the stjepang:fix-lifetime-issues branch Jul 27, 2018

@stjepang stjepang referenced this pull request Jul 27, 2018

Open

Tracking issue for RFC 2115: In-band lifetime bindings #44524

3 of 10 tasks complete
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.