9
9
// except according to those terms.
10
10
11
11
//! 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" ) ]
38
14
39
15
use prelude:: v1:: * ;
40
16
41
17
use cell:: UnsafeCell ;
42
18
43
- #[ macro_use]
44
- pub mod scoped;
45
-
46
19
// Sure wish we had macro hygiene, no?
47
20
#[ doc( hidden) ]
48
21
#[ unstable( feature = "thread_local_internals" ) ]
@@ -95,7 +68,7 @@ pub mod __impl {
95
68
/// });
96
69
/// ```
97
70
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
98
- pub struct Key < T > {
71
+ pub struct LocalKey < T > {
99
72
// The key itself may be tagged with #[thread_local], and this `Key` is
100
73
// stored as a `static`, and it's not valid for a static to reference the
101
74
// address of another thread_local static. For this reason we kinda wonkily
@@ -114,15 +87,15 @@ pub struct Key<T> {
114
87
pub init : fn ( ) -> T ,
115
88
}
116
89
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 `.
118
91
#[ macro_export]
119
92
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
120
93
#[ allow_internal_unstable]
121
94
macro_rules! thread_local {
122
95
( static $name: ident: $t: ty = $init: expr) => (
123
- static $name: :: std:: thread_local :: Key <$t> = {
96
+ static $name: :: std:: thread :: LocalKey <$t> = {
124
97
use std:: cell:: UnsafeCell as __UnsafeCell;
125
- use std:: thread_local :: __impl:: KeyInner as __KeyInner;
98
+ use std:: thread :: __local :: __impl:: KeyInner as __KeyInner;
126
99
use std:: option:: Option as __Option;
127
100
use std:: option:: Option :: None as __None;
128
101
@@ -133,13 +106,13 @@ macro_rules! thread_local {
133
106
fn __getit( ) -> & ' static __KeyInner<__UnsafeCell<__Option<$t>>> {
134
107
& __KEY
135
108
}
136
- :: std:: thread_local :: Key { inner: __getit, init: __init }
109
+ :: std:: thread :: LocalKey { inner: __getit, init: __init }
137
110
} ;
138
111
) ;
139
112
( 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> = {
141
114
use std:: cell:: UnsafeCell as __UnsafeCell;
142
- use std:: thread_local :: __impl:: KeyInner as __KeyInner;
115
+ use std:: thread :: __local :: __impl:: KeyInner as __KeyInner;
143
116
use std:: option:: Option as __Option;
144
117
use std:: option:: Option :: None as __None;
145
118
@@ -150,7 +123,7 @@ macro_rules! thread_local {
150
123
fn __getit( ) -> & ' static __KeyInner<__UnsafeCell<__Option<$t>>> {
151
124
& __KEY
152
125
}
153
- :: std:: thread_local :: Key { inner: __getit, init: __init }
126
+ :: std:: thread :: LocalKey { inner: __getit, init: __init }
154
127
} ;
155
128
) ;
156
129
}
@@ -183,36 +156,36 @@ macro_rules! __thread_local_inner {
183
156
#[ cfg_attr( all( any( target_os = "macos" , target_os = "linux" ) ,
184
157
not( target_arch = "aarch64" ) ) ,
185
158
thread_local) ]
186
- static $name: :: std:: thread_local :: __impl:: KeyInner <$t> =
159
+ static $name: :: std:: thread :: __local :: __impl:: KeyInner <$t> =
187
160
__thread_local_inner!( $init, $t) ;
188
161
) ;
189
162
( pub static $name: ident: $t: ty = $init: expr) => (
190
163
#[ cfg_attr( all( any( target_os = "macos" , target_os = "linux" ) ,
191
164
not( target_arch = "aarch64" ) ) ,
192
165
thread_local) ]
193
- pub static $name: :: std:: thread_local :: __impl:: KeyInner <$t> =
166
+ pub static $name: :: std:: thread :: __local :: __impl:: KeyInner <$t> =
194
167
__thread_local_inner!( $init, $t) ;
195
168
) ;
196
169
( $init: expr, $t: ty) => ( {
197
170
#[ 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 {
200
173
inner: :: std:: cell:: UnsafeCell { value: $init } ,
201
174
dtor_registered: :: std:: cell:: UnsafeCell { value: false } ,
202
175
dtor_running: :: std:: cell:: UnsafeCell { value: false } ,
203
176
}
204
177
} ;
205
178
206
179
#[ 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> = {
208
181
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) ;
210
183
}
211
184
212
- :: std:: thread_local :: __impl:: KeyInner {
185
+ :: std:: thread :: __local :: __impl:: KeyInner {
213
186
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 ,
216
189
dtor: :: std:: option:: Option :: Some ( __destroy as unsafe extern fn ( * mut u8 ) ) ,
217
190
} ,
218
191
}
@@ -226,7 +199,7 @@ macro_rules! __thread_local_inner {
226
199
#[ unstable( feature = "std_misc" ,
227
200
reason = "state querying was recently added" ) ]
228
201
#[ derive( Eq , PartialEq , Copy ) ]
229
- pub enum State {
202
+ pub enum LocalKeyState {
230
203
/// All keys are in this state whenever a thread starts. Keys will
231
204
/// transition to the `Valid` state once the first call to `with` happens
232
205
/// and the initialization expression succeeds.
@@ -253,7 +226,7 @@ pub enum State {
253
226
Destroyed ,
254
227
}
255
228
256
- impl < T : ' static > Key < T > {
229
+ impl < T : ' static > LocalKey < T > {
257
230
/// Acquire a reference to the value in this TLS key.
258
231
///
259
232
/// This will lazily initialize the value if this thread has not referenced
@@ -309,16 +282,16 @@ impl<T: 'static> Key<T> {
309
282
/// any call to `with`.
310
283
#[ unstable( feature = "std_misc" ,
311
284
reason = "state querying was recently added" ) ]
312
- pub fn state ( & ' static self ) -> State {
285
+ pub fn state ( & ' static self ) -> LocalKeyState {
313
286
unsafe {
314
287
match ( self . inner ) ( ) . get ( ) {
315
288
Some ( cell) => {
316
289
match * cell. get ( ) {
317
- Some ( ..) => State :: Valid ,
318
- None => State :: Uninitialized ,
290
+ Some ( ..) => LocalKeyState :: Valid ,
291
+ None => LocalKeyState :: Uninitialized ,
319
292
}
320
293
}
321
- None => State :: Destroyed ,
294
+ None => LocalKeyState :: Destroyed ,
322
295
}
323
296
}
324
297
}
@@ -327,7 +300,7 @@ impl<T: 'static> Key<T> {
327
300
#[ unstable( feature = "std_misc" ) ]
328
301
#[ deprecated( since = "1.0.0" ,
329
302
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 }
331
304
}
332
305
333
306
#[ cfg( all( any( target_os = "macos" , target_os = "linux" ) , not( target_arch = "aarch64" ) ) ) ]
@@ -553,7 +526,7 @@ mod tests {
553
526
554
527
use sync:: mpsc:: { channel, Sender } ;
555
528
use cell:: UnsafeCell ;
556
- use super :: State ;
529
+ use super :: LocalKeyState ;
557
530
use thread;
558
531
559
532
struct Foo ( Sender < ( ) > ) ;
@@ -592,21 +565,21 @@ mod tests {
592
565
struct Foo ;
593
566
impl Drop for Foo {
594
567
fn drop ( & mut self ) {
595
- assert ! ( FOO . state( ) == State :: Destroyed ) ;
568
+ assert ! ( FOO . state( ) == LocalKeyState :: Destroyed ) ;
596
569
}
597
570
}
598
571
fn foo ( ) -> Foo {
599
- assert ! ( FOO . state( ) == State :: Uninitialized ) ;
572
+ assert ! ( FOO . state( ) == LocalKeyState :: Uninitialized ) ;
600
573
Foo
601
574
}
602
575
thread_local ! ( static FOO : Foo = foo( ) ) ;
603
576
604
577
thread:: spawn ( || {
605
- assert ! ( FOO . state( ) == State :: Uninitialized ) ;
578
+ assert ! ( FOO . state( ) == LocalKeyState :: Uninitialized ) ;
606
579
FOO . with ( |_| {
607
- assert ! ( FOO . state( ) == State :: Valid ) ;
580
+ assert ! ( FOO . state( ) == LocalKeyState :: Valid ) ;
608
581
} ) ;
609
- assert ! ( FOO . state( ) == State :: Valid ) ;
582
+ assert ! ( FOO . state( ) == LocalKeyState :: Valid ) ;
610
583
} ) . join ( ) . ok ( ) . unwrap ( ) ;
611
584
}
612
585
@@ -642,7 +615,7 @@ mod tests {
642
615
fn drop ( & mut self ) {
643
616
unsafe {
644
617
HITS += 1 ;
645
- if K2 . state ( ) == State :: Destroyed {
618
+ if K2 . state ( ) == LocalKeyState :: Destroyed {
646
619
assert_eq ! ( HITS , 3 ) ;
647
620
} else {
648
621
if HITS == 1 {
@@ -658,7 +631,7 @@ mod tests {
658
631
fn drop ( & mut self ) {
659
632
unsafe {
660
633
HITS += 1 ;
661
- assert ! ( K1 . state( ) != State :: Destroyed ) ;
634
+ assert ! ( K1 . state( ) != LocalKeyState :: Destroyed ) ;
662
635
assert_eq ! ( HITS , 2 ) ;
663
636
K1 . with ( |s| * s. get ( ) = Some ( S1 ) ) ;
664
637
}
@@ -679,7 +652,7 @@ mod tests {
679
652
680
653
impl Drop for S1 {
681
654
fn drop ( & mut self ) {
682
- assert ! ( K1 . state( ) == State :: Destroyed ) ;
655
+ assert ! ( K1 . state( ) == LocalKeyState :: Destroyed ) ;
683
656
}
684
657
}
685
658
@@ -702,7 +675,7 @@ mod tests {
702
675
fn drop ( & mut self ) {
703
676
let S1 ( ref tx) = * self ;
704
677
unsafe {
705
- if K2 . state ( ) != State :: Destroyed {
678
+ if K2 . state ( ) != LocalKeyState :: Destroyed {
706
679
K2 . with ( |s| * s. get ( ) = Some ( Foo ( tx. clone ( ) ) ) ) ;
707
680
}
708
681
}
0 commit comments