Skip to content

Commit 6bd3ab0

Browse files
committed
Implement RFC 909: move thread_local into thread
This commit implements [RFC 909](rust-lang/rfcs#909): The `std::thread_local` module is now deprecated, and its contents are available directly in `std::thread` as `LocalKey`, `LocalKeyState`, and `ScopedKey`. The macros remain exactly as they were, which means little if any code should break. Nevertheless, this is technically a: [breaking-change] Closes #23547
1 parent b0aad7d commit 6bd3ab0

File tree

5 files changed

+127
-91
lines changed

5 files changed

+127
-91
lines changed

src/libstd/lib.rs

+8-15
Original file line numberDiff line numberDiff line change
@@ -249,30 +249,23 @@ pub mod num;
249249
/* Runtime and platform support */
250250

251251
#[macro_use]
252-
pub mod thread_local;
252+
pub mod thread;
253253

254+
pub mod collections;
254255
pub mod dynamic_lib;
256+
pub mod env;
255257
pub mod ffi;
256-
pub mod old_io;
257-
pub mod io;
258258
pub mod fs;
259+
pub mod io;
259260
pub mod net;
261+
pub mod old_io;
262+
pub mod old_path;
260263
pub mod os;
261-
pub mod env;
262264
pub mod path;
263-
pub mod old_path;
264265
pub mod process;
265266
pub mod rand;
266-
pub mod time;
267-
268-
/* Common data structures */
269-
270-
pub mod collections;
271-
272-
/* Threads and communication */
273-
274-
pub mod thread;
275267
pub mod sync;
268+
pub mod time;
276269

277270
#[macro_use]
278271
#[path = "sys/common/mod.rs"] mod sys_common;
@@ -305,7 +298,7 @@ mod std {
305298
pub use rt; // used for panic!()
306299
pub use vec; // used for vec![]
307300
pub use cell; // used for tls!
308-
pub use thread_local; // used for thread_local!
301+
pub use thread; // used for thread_local!
309302
pub use marker; // used for tls!
310303
pub use ops; // used for bitflags!
311304

src/libstd/sys/common/thread_info.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use core::prelude::*;
1515
use cell::RefCell;
1616
use string::String;
1717
use thread::Thread;
18-
use thread_local::State;
18+
use thread::LocalKeyState;
1919

2020
struct ThreadInfo {
2121
stack_guard: uint,
@@ -26,7 +26,7 @@ thread_local! { static THREAD_INFO: RefCell<Option<ThreadInfo>> = RefCell::new(N
2626

2727
impl ThreadInfo {
2828
fn with<R, F>(f: F) -> R where F: FnOnce(&mut ThreadInfo) -> R {
29-
if THREAD_INFO.state() == State::Destroyed {
29+
if THREAD_INFO.state() == LocalKeyState::Destroyed {
3030
panic!("Use of std::thread::current() is not possible after \
3131
the thread's local data has been destroyed");
3232
}

src/libstd/thread_local/mod.rs renamed to src/libstd/thread/local.rs

+36-63
Original file line numberDiff line numberDiff line change
@@ -9,40 +9,13 @@
99
// except according to those terms.
1010

1111
//! Thread local storage
12-
//!
13-
//! This module provides an implementation of thread local storage for Rust
14-
//! programs. Thread local storage is a method of storing data into a global
15-
//! variable which each thread in the program will have its own copy of.
16-
//! Threads do not share this data, so accesses do not need to be synchronized.
17-
//!
18-
//! At a high level, this module provides two variants of storage:
19-
//!
20-
//! * Owning thread local storage. This is a type of thread local key which
21-
//! owns the value that it contains, and will destroy the value when the
22-
//! thread exits. This variant is created with the `thread_local!` macro and
23-
//! can contain any value which is `'static` (no borrowed pointers.
24-
//!
25-
//! * Scoped thread local storage. This type of key is used to store a reference
26-
//! to a value into local storage temporarily for the scope of a function
27-
//! call. There are no restrictions on what types of values can be placed
28-
//! into this key.
29-
//!
30-
//! Both forms of thread local storage provide an accessor function, `with`,
31-
//! which will yield a shared reference to the value to the specified
32-
//! closure. Thread local keys only allow shared access to values as there is no
33-
//! way to guarantee uniqueness if a mutable borrow was allowed. Most values
34-
//! will want to make use of some form of **interior mutability** through the
35-
//! `Cell` or `RefCell` types.
36-
37-
#![stable(feature = "rust1", since = "1.0.0")]
12+
13+
#![unstable(feature = "thread_local_internals")]
3814

3915
use prelude::v1::*;
4016

4117
use cell::UnsafeCell;
4218

43-
#[macro_use]
44-
pub mod scoped;
45-
4619
// Sure wish we had macro hygiene, no?
4720
#[doc(hidden)]
4821
#[unstable(feature = "thread_local_internals")]
@@ -95,7 +68,7 @@ pub mod __impl {
9568
/// });
9669
/// ```
9770
#[stable(feature = "rust1", since = "1.0.0")]
98-
pub struct Key<T> {
71+
pub struct LocalKey<T> {
9972
// The key itself may be tagged with #[thread_local], and this `Key` is
10073
// stored as a `static`, and it's not valid for a static to reference the
10174
// address of another thread_local static. For this reason we kinda wonkily
@@ -114,15 +87,15 @@ pub struct Key<T> {
11487
pub init: fn() -> T,
11588
}
11689

117-
/// Declare a new thread local storage key of type `std::thread_local::Key`.
90+
/// Declare a new thread local storage key of type `std::thread::LocalKey`.
11891
#[macro_export]
11992
#[stable(feature = "rust1", since = "1.0.0")]
12093
#[allow_internal_unstable]
12194
macro_rules! thread_local {
12295
(static $name:ident: $t:ty = $init:expr) => (
123-
static $name: ::std::thread_local::Key<$t> = {
96+
static $name: ::std::thread::LocalKey<$t> = {
12497
use std::cell::UnsafeCell as __UnsafeCell;
125-
use std::thread_local::__impl::KeyInner as __KeyInner;
98+
use std::thread::__local::__impl::KeyInner as __KeyInner;
12699
use std::option::Option as __Option;
127100
use std::option::Option::None as __None;
128101

@@ -133,13 +106,13 @@ macro_rules! thread_local {
133106
fn __getit() -> &'static __KeyInner<__UnsafeCell<__Option<$t>>> {
134107
&__KEY
135108
}
136-
::std::thread_local::Key { inner: __getit, init: __init }
109+
::std::thread::LocalKey { inner: __getit, init: __init }
137110
};
138111
);
139112
(pub static $name:ident: $t:ty = $init:expr) => (
140-
pub static $name: ::std::thread_local::Key<$t> = {
113+
pub static $name: ::std::thread::LocalKey<$t> = {
141114
use std::cell::UnsafeCell as __UnsafeCell;
142-
use std::thread_local::__impl::KeyInner as __KeyInner;
115+
use std::thread::__local::__impl::KeyInner as __KeyInner;
143116
use std::option::Option as __Option;
144117
use std::option::Option::None as __None;
145118

@@ -150,7 +123,7 @@ macro_rules! thread_local {
150123
fn __getit() -> &'static __KeyInner<__UnsafeCell<__Option<$t>>> {
151124
&__KEY
152125
}
153-
::std::thread_local::Key { inner: __getit, init: __init }
126+
::std::thread::LocalKey { inner: __getit, init: __init }
154127
};
155128
);
156129
}
@@ -183,36 +156,36 @@ macro_rules! __thread_local_inner {
183156
#[cfg_attr(all(any(target_os = "macos", target_os = "linux"),
184157
not(target_arch = "aarch64")),
185158
thread_local)]
186-
static $name: ::std::thread_local::__impl::KeyInner<$t> =
159+
static $name: ::std::thread::__local::__impl::KeyInner<$t> =
187160
__thread_local_inner!($init, $t);
188161
);
189162
(pub static $name:ident: $t:ty = $init:expr) => (
190163
#[cfg_attr(all(any(target_os = "macos", target_os = "linux"),
191164
not(target_arch = "aarch64")),
192165
thread_local)]
193-
pub static $name: ::std::thread_local::__impl::KeyInner<$t> =
166+
pub static $name: ::std::thread::__local::__impl::KeyInner<$t> =
194167
__thread_local_inner!($init, $t);
195168
);
196169
($init:expr, $t:ty) => ({
197170
#[cfg(all(any(target_os = "macos", target_os = "linux"), not(target_arch = "aarch64")))]
198-
const _INIT: ::std::thread_local::__impl::KeyInner<$t> = {
199-
::std::thread_local::__impl::KeyInner {
171+
const _INIT: ::std::thread::__local::__impl::KeyInner<$t> = {
172+
::std::thread::__local::__impl::KeyInner {
200173
inner: ::std::cell::UnsafeCell { value: $init },
201174
dtor_registered: ::std::cell::UnsafeCell { value: false },
202175
dtor_running: ::std::cell::UnsafeCell { value: false },
203176
}
204177
};
205178

206179
#[cfg(any(not(any(target_os = "macos", target_os = "linux")), target_arch = "aarch64"))]
207-
const _INIT: ::std::thread_local::__impl::KeyInner<$t> = {
180+
const _INIT: ::std::thread::__local::__impl::KeyInner<$t> = {
208181
unsafe extern fn __destroy(ptr: *mut u8) {
209-
::std::thread_local::__impl::destroy_value::<$t>(ptr);
182+
::std::thread::__local::__impl::destroy_value::<$t>(ptr);
210183
}
211184

212-
::std::thread_local::__impl::KeyInner {
185+
::std::thread::__local::__impl::KeyInner {
213186
inner: ::std::cell::UnsafeCell { value: $init },
214-
os: ::std::thread_local::__impl::OsStaticKey {
215-
inner: ::std::thread_local::__impl::OS_INIT_INNER,
187+
os: ::std::thread::__local::__impl::OsStaticKey {
188+
inner: ::std::thread::__local::__impl::OS_INIT_INNER,
216189
dtor: ::std::option::Option::Some(__destroy as unsafe extern fn(*mut u8)),
217190
},
218191
}
@@ -226,7 +199,7 @@ macro_rules! __thread_local_inner {
226199
#[unstable(feature = "std_misc",
227200
reason = "state querying was recently added")]
228201
#[derive(Eq, PartialEq, Copy)]
229-
pub enum State {
202+
pub enum LocalKeyState {
230203
/// All keys are in this state whenever a thread starts. Keys will
231204
/// transition to the `Valid` state once the first call to `with` happens
232205
/// and the initialization expression succeeds.
@@ -253,7 +226,7 @@ pub enum State {
253226
Destroyed,
254227
}
255228

256-
impl<T: 'static> Key<T> {
229+
impl<T: 'static> LocalKey<T> {
257230
/// Acquire a reference to the value in this TLS key.
258231
///
259232
/// This will lazily initialize the value if this thread has not referenced
@@ -309,16 +282,16 @@ impl<T: 'static> Key<T> {
309282
/// any call to `with`.
310283
#[unstable(feature = "std_misc",
311284
reason = "state querying was recently added")]
312-
pub fn state(&'static self) -> State {
285+
pub fn state(&'static self) -> LocalKeyState {
313286
unsafe {
314287
match (self.inner)().get() {
315288
Some(cell) => {
316289
match *cell.get() {
317-
Some(..) => State::Valid,
318-
None => State::Uninitialized,
290+
Some(..) => LocalKeyState::Valid,
291+
None => LocalKeyState::Uninitialized,
319292
}
320293
}
321-
None => State::Destroyed,
294+
None => LocalKeyState::Destroyed,
322295
}
323296
}
324297
}
@@ -327,7 +300,7 @@ impl<T: 'static> Key<T> {
327300
#[unstable(feature = "std_misc")]
328301
#[deprecated(since = "1.0.0",
329302
reason = "function renamed to state() and returns more info")]
330-
pub fn destroyed(&'static self) -> bool { self.state() == State::Destroyed }
303+
pub fn destroyed(&'static self) -> bool { self.state() == LocalKeyState::Destroyed }
331304
}
332305

333306
#[cfg(all(any(target_os = "macos", target_os = "linux"), not(target_arch = "aarch64")))]
@@ -553,7 +526,7 @@ mod tests {
553526

554527
use sync::mpsc::{channel, Sender};
555528
use cell::UnsafeCell;
556-
use super::State;
529+
use super::LocalKeyState;
557530
use thread;
558531

559532
struct Foo(Sender<()>);
@@ -592,21 +565,21 @@ mod tests {
592565
struct Foo;
593566
impl Drop for Foo {
594567
fn drop(&mut self) {
595-
assert!(FOO.state() == State::Destroyed);
568+
assert!(FOO.state() == LocalKeyState::Destroyed);
596569
}
597570
}
598571
fn foo() -> Foo {
599-
assert!(FOO.state() == State::Uninitialized);
572+
assert!(FOO.state() == LocalKeyState::Uninitialized);
600573
Foo
601574
}
602575
thread_local!(static FOO: Foo = foo());
603576

604577
thread::spawn(|| {
605-
assert!(FOO.state() == State::Uninitialized);
578+
assert!(FOO.state() == LocalKeyState::Uninitialized);
606579
FOO.with(|_| {
607-
assert!(FOO.state() == State::Valid);
580+
assert!(FOO.state() == LocalKeyState::Valid);
608581
});
609-
assert!(FOO.state() == State::Valid);
582+
assert!(FOO.state() == LocalKeyState::Valid);
610583
}).join().ok().unwrap();
611584
}
612585

@@ -642,7 +615,7 @@ mod tests {
642615
fn drop(&mut self) {
643616
unsafe {
644617
HITS += 1;
645-
if K2.state() == State::Destroyed {
618+
if K2.state() == LocalKeyState::Destroyed {
646619
assert_eq!(HITS, 3);
647620
} else {
648621
if HITS == 1 {
@@ -658,7 +631,7 @@ mod tests {
658631
fn drop(&mut self) {
659632
unsafe {
660633
HITS += 1;
661-
assert!(K1.state() != State::Destroyed);
634+
assert!(K1.state() != LocalKeyState::Destroyed);
662635
assert_eq!(HITS, 2);
663636
K1.with(|s| *s.get() = Some(S1));
664637
}
@@ -679,7 +652,7 @@ mod tests {
679652

680653
impl Drop for S1 {
681654
fn drop(&mut self) {
682-
assert!(K1.state() == State::Destroyed);
655+
assert!(K1.state() == LocalKeyState::Destroyed);
683656
}
684657
}
685658

@@ -702,7 +675,7 @@ mod tests {
702675
fn drop(&mut self) {
703676
let S1(ref tx) = *self;
704677
unsafe {
705-
if K2.state() != State::Destroyed {
678+
if K2.state() != LocalKeyState::Destroyed {
706679
K2.with(|s| *s.get() = Some(Foo(tx.clone())));
707680
}
708681
}

0 commit comments

Comments
 (0)