diff options
| author | Aaron Turon <aturon@mozilla.com> | 2015-04-13 12:08:20 -0700 |
|---|---|---|
| committer | Aaron Turon <aturon@mozilla.com> | 2015-04-13 12:15:28 -0700 |
| commit | 6399bb425b3a82111cd554737f194c95b8f6bad5 (patch) | |
| tree | f1799d53b1c70ba745ac6c0d82da3fe6d2b26b23 /src/libstd/thread | |
| parent | 588d37c653ddac491c2c1cb8974f56781533b173 (diff) | |
| download | rust-6399bb425b3a82111cd554737f194c95b8f6bad5.tar.gz rust-6399bb425b3a82111cd554737f194c95b8f6bad5.zip | |
De-stabilize `thread::scoped` and friends
Issue #24292 demonstrates that the `scoped` API as currently offered can be memory-unsafe: the `JoinGuard` can be moved into a context that will fail to execute destructors prior to the stack frame being popped (for example, by creating an `Rc` cycle). This commit reverts the APIs to `unstable` status while a long-term solution is worked out. (There are several possible ways to address this issue; it's not a fundamental problem with the `scoped` idea, but rather an indication that Rust doesn't currently provide a good way to ensure that destructors are run within a particular stack frame.) [breaking-change]
Diffstat (limited to 'src/libstd/thread')
| -rw-r--r-- | src/libstd/thread/mod.rs | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 0e5fee27ffe..23991102650 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -274,7 +274,8 @@ impl Builder { /// Unlike the `scoped` free function, this method yields an /// `io::Result` to capture any failure to create the thread at /// the OS level. - #[stable(feature = "rust1", since = "1.0.0")] + #[unstable(feature = "scoped", + reason = "memory unsafe if destructor is avoided, see #24292")] pub fn scoped<'a, T, F>(self, f: F) -> io::Result<JoinGuard<'a, T>> where T: Send + 'a, F: FnOnce() -> T, F: Send + 'a { @@ -387,7 +388,8 @@ pub fn spawn<F>(f: F) -> JoinHandle where F: FnOnce(), F: Send + 'static { /// /// Panics if the OS fails to create a thread; use `Builder::scoped` /// to recover from such errors. -#[stable(feature = "rust1", since = "1.0.0")] +#[unstable(feature = "scoped", + reason = "memory unsafe if destructor is avoided, see #24292")] pub fn scoped<'a, T, F>(f: F) -> JoinGuard<'a, T> where T: Send + 'a, F: FnOnce() -> T, F: Send + 'a { @@ -674,7 +676,8 @@ impl Drop for JoinHandle { /// handle: the ability to join a child thread is a uniquely-owned /// permission. #[must_use = "thread will be immediately joined if `JoinGuard` is not used"] -#[stable(feature = "rust1", since = "1.0.0")] +#[unstable(feature = "scoped", + reason = "memory unsafe if destructor is avoided, see #24292")] pub struct JoinGuard<'a, T: Send + 'a> { inner: JoinInner<T>, _marker: PhantomData<&'a T>, @@ -706,7 +709,8 @@ impl<'a, T: Send + 'a> JoinGuard<'a, T> { } #[unsafe_destructor] -#[stable(feature = "rust1", since = "1.0.0")] +#[unstable(feature = "scoped", + reason = "memory unsafe if destructor is avoided, see #24292")] impl<'a, T: Send + 'a> Drop for JoinGuard<'a, T> { fn drop(&mut self) { if !self.inner.joined { |
