diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2014-11-14 14:20:57 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2014-11-23 23:37:16 -0800 |
| commit | a9c1152c4bf72132806cb76045b3464d59db07da (patch) | |
| tree | 89ba92d5f5788e3323b75ca003bf74661a94e4de /src/libstd/collections | |
| parent | 4e5259503cd8aac9905c7ac6d68d0c4caab1d28c (diff) | |
| download | rust-a9c1152c4bf72132806cb76045b3464d59db07da.tar.gz rust-a9c1152c4bf72132806cb76045b3464d59db07da.zip | |
std: Add a new top-level thread_local module
This commit removes the `std::local_data` module in favor of a new
`std::thread_local` module providing thread local storage. The module provides
two variants of TLS: one which owns its contents and one which is based on
scoped references. Each implementation has pros and cons listed in the
documentation.
Both flavors have accessors through a function called `with` which yield a
reference to a closure provided. Both flavors also panic if a reference cannot
be yielded and provide a function to test whether an access would panic or not.
This is an implementation of [RFC 461][rfc] and full details can be found in
that RFC.
This is a breaking change due to the removal of the `std::local_data` module.
All users can migrate to the new thread local system like so:
thread_local!(static FOO: Rc<RefCell<Option<T>>> = Rc::new(RefCell::new(None)))
The old `local_data` module inherently contained the `Rc<RefCell<Option<T>>>` as
an implementation detail which must now be explicitly stated by users.
[rfc]: https://github.com/rust-lang/rfcs/pull/461
[breaking-change]
Diffstat (limited to 'src/libstd/collections')
| -rw-r--r-- | src/libstd/collections/hash/map.rs | 133 |
1 files changed, 72 insertions, 61 deletions
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 69375e8d4f8..662ae913764 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1471,7 +1471,7 @@ mod test_map { assert_eq!(*m.get(&2).unwrap(), 4); } - local_data_key!(drop_vector: RefCell<Vec<int>>) + thread_local!(static DROP_VECTOR: RefCell<Vec<int>> = RefCell::new(Vec::new())) #[deriving(Hash, PartialEq, Eq)] struct Dropable { @@ -1480,8 +1480,9 @@ mod test_map { impl Dropable { fn new(k: uint) -> Dropable { - let v = drop_vector.get().unwrap(); - v.borrow_mut().as_mut_slice()[k] += 1; + DROP_VECTOR.with(|slot| { + slot.borrow_mut()[k] += 1; + }); Dropable { k: k } } @@ -1489,8 +1490,9 @@ mod test_map { impl Drop for Dropable { fn drop(&mut self) { - let v = drop_vector.get().unwrap(); - v.borrow_mut().as_mut_slice()[self.k] -= 1; + DROP_VECTOR.with(|slot| { + slot.borrow_mut()[self.k] -= 1; + }); } } @@ -1502,16 +1504,18 @@ mod test_map { #[test] fn test_drops() { - drop_vector.replace(Some(RefCell::new(Vec::from_elem(200, 0i)))); + DROP_VECTOR.with(|slot| { + *slot.borrow_mut() = Vec::from_elem(200, 0i); + }); { let mut m = HashMap::new(); - let v = drop_vector.get().unwrap(); - for i in range(0u, 200) { - assert_eq!(v.borrow().as_slice()[i], 0); - } - drop(v); + DROP_VECTOR.with(|v| { + for i in range(0u, 200) { + assert_eq!(v.borrow().as_slice()[i], 0); + } + }); for i in range(0u, 100) { let d1 = Dropable::new(i); @@ -1519,11 +1523,11 @@ mod test_map { m.insert(d1, d2); } - let v = drop_vector.get().unwrap(); - for i in range(0u, 200) { - assert_eq!(v.borrow().as_slice()[i], 1); - } - drop(v); + DROP_VECTOR.with(|v| { + for i in range(0u, 200) { + assert_eq!(v.borrow().as_slice()[i], 1); + } + }); for i in range(0u, 50) { let k = Dropable::new(i); @@ -1531,41 +1535,46 @@ mod test_map { assert!(v.is_some()); - let v = drop_vector.get().unwrap(); - assert_eq!(v.borrow().as_slice()[i], 1); - assert_eq!(v.borrow().as_slice()[i+100], 1); + DROP_VECTOR.with(|v| { + assert_eq!(v.borrow().as_slice()[i], 1); + assert_eq!(v.borrow().as_slice()[i+100], 1); + }); } - let v = drop_vector.get().unwrap(); - for i in range(0u, 50) { - assert_eq!(v.borrow().as_slice()[i], 0); - assert_eq!(v.borrow().as_slice()[i+100], 0); - } + DROP_VECTOR.with(|v| { + for i in range(0u, 50) { + assert_eq!(v.borrow().as_slice()[i], 0); + assert_eq!(v.borrow().as_slice()[i+100], 0); + } - for i in range(50u, 100) { - assert_eq!(v.borrow().as_slice()[i], 1); - assert_eq!(v.borrow().as_slice()[i+100], 1); - } + for i in range(50u, 100) { + assert_eq!(v.borrow().as_slice()[i], 1); + assert_eq!(v.borrow().as_slice()[i+100], 1); + } + }); } - let v = drop_vector.get().unwrap(); - for i in range(0u, 200) { - assert_eq!(v.borrow().as_slice()[i], 0); - } + DROP_VECTOR.with(|v| { + for i in range(0u, 200) { + assert_eq!(v.borrow().as_slice()[i], 0); + } + }); } #[test] fn test_move_iter_drops() { - drop_vector.replace(Some(RefCell::new(Vec::from_elem(200, 0i)))); + DROP_VECTOR.with(|v| { + *v.borrow_mut() = Vec::from_elem(200, 0i); + }); let hm = { let mut hm = HashMap::new(); - let v = drop_vector.get().unwrap(); - for i in range(0u, 200) { - assert_eq!(v.borrow().as_slice()[i], 0); - } - drop(v); + DROP_VECTOR.with(|v| { + for i in range(0u, 200) { + assert_eq!(v.borrow().as_slice()[i], 0); + } + }); for i in range(0u, 100) { let d1 = Dropable::new(i); @@ -1573,11 +1582,11 @@ mod test_map { hm.insert(d1, d2); } - let v = drop_vector.get().unwrap(); - for i in range(0u, 200) { - assert_eq!(v.borrow().as_slice()[i], 1); - } - drop(v); + DROP_VECTOR.with(|v| { + for i in range(0u, 200) { + assert_eq!(v.borrow().as_slice()[i], 1); + } + }); hm }; @@ -1588,31 +1597,33 @@ mod test_map { { let mut half = hm.into_iter().take(50); - let v = drop_vector.get().unwrap(); - for i in range(0u, 200) { - assert_eq!(v.borrow().as_slice()[i], 1); - } - drop(v); + DROP_VECTOR.with(|v| { + for i in range(0u, 200) { + assert_eq!(v.borrow().as_slice()[i], 1); + } + }); for _ in half {} - let v = drop_vector.get().unwrap(); - let nk = range(0u, 100).filter(|&i| { - v.borrow().as_slice()[i] == 1 - }).count(); + DROP_VECTOR.with(|v| { + let nk = range(0u, 100).filter(|&i| { + v.borrow().as_slice()[i] == 1 + }).count(); - let nv = range(0u, 100).filter(|&i| { - v.borrow().as_slice()[i+100] == 1 - }).count(); + let nv = range(0u, 100).filter(|&i| { + v.borrow().as_slice()[i+100] == 1 + }).count(); - assert_eq!(nk, 50); - assert_eq!(nv, 50); + assert_eq!(nk, 50); + assert_eq!(nv, 50); + }); }; - let v = drop_vector.get().unwrap(); - for i in range(0u, 200) { - assert_eq!(v.borrow().as_slice()[i], 0); - } + DROP_VECTOR.with(|v| { + for i in range(0u, 200) { + assert_eq!(v.borrow().as_slice()[i], 0); + } + }); } #[test] |
