Skip to content

Commit 07183ea

Browse files
committed
auto merge of #7677 : alexcrichton/rust/tls-gc, r=pcwalton
cc #6004 and #3273 This is a rewrite of TLS to get towards not requiring `@` when using task local storage. Most of the rewrite is straightforward, although there are two caveats: 1. Changing `local_set` to not require `@` is blocked on #7673 2. The code in `local_pop` is some of the most unsafe code I've written. A second set of eyes should definitely scrutinize it... The public-facing interface currently hasn't changed, although it will have to change because `local_data::get` cannot return `Option<T>`, nor can it return `Option<&T>` (the lifetime isn't known). This will have to be changed to be given a closure which yield `&T` (or as an Option). I didn't do this part of the api rewrite in this pull request as I figured that it could wait until when `@` is fully removed. This also doesn't deal with the issue of using something other than functions as keys, but I'm looking into using static slices (as mentioned in the issues).
2 parents 9a9c84f + a15c1b4 commit 07183ea

20 files changed

+617
-274
lines changed

src/libextra/rl.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,11 @@ fn complete_key(_v: @CompletionCb) {}
7272

7373
/// Bind to the main completion callback
7474
pub unsafe fn complete(cb: CompletionCb) {
75-
local_data::local_data_set(complete_key, @(cb));
75+
local_data::set(complete_key, @(cb));
7676

7777
extern fn callback(line: *c_char, completions: *()) {
7878
unsafe {
79-
let cb = *local_data::local_data_get(complete_key)
79+
let cb = *local_data::get(complete_key, |k| k.map(|&k| *k))
8080
.get();
8181

8282
do cb(str::raw::from_c_str(line)) |suggestion| {

src/libextra/sort.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1204,11 +1204,11 @@ mod big_tests {
12041204
#[unsafe_destructor]
12051205
impl<'self> Drop for LVal<'self> {
12061206
fn drop(&self) {
1207-
let x = unsafe { local_data::local_data_get(self.key) };
1207+
let x = unsafe { local_data::get(self.key, |k| k.map(|&k| *k)) };
12081208
match x {
12091209
Some(@y) => {
12101210
unsafe {
1211-
local_data::local_data_set(self.key, @(y+1));
1211+
local_data::set(self.key, @(y+1));
12121212
}
12131213
}
12141214
_ => fail!("Expected key to work"),

src/librustc/middle/trans/base.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ fn task_local_insn_key(_v: @~[&'static str]) {}
9191

9292
pub fn with_insn_ctxt(blk: &fn(&[&'static str])) {
9393
unsafe {
94-
let opt = local_data::local_data_get(task_local_insn_key);
94+
let opt = local_data::get(task_local_insn_key, |k| k.map(|&k| *k));
9595
if opt.is_some() {
9696
blk(*opt.unwrap());
9797
}
@@ -100,7 +100,7 @@ pub fn with_insn_ctxt(blk: &fn(&[&'static str])) {
100100

101101
pub fn init_insn_ctxt() {
102102
unsafe {
103-
local_data::local_data_set(task_local_insn_key, @~[]);
103+
local_data::set(task_local_insn_key, @~[]);
104104
}
105105
}
106106

@@ -110,7 +110,7 @@ pub struct _InsnCtxt { _x: () }
110110
impl Drop for _InsnCtxt {
111111
fn drop(&self) {
112112
unsafe {
113-
do local_data::local_data_modify(task_local_insn_key) |c| {
113+
do local_data::modify(task_local_insn_key) |c| {
114114
do c.map_consume |ctx| {
115115
let mut ctx = copy *ctx;
116116
ctx.pop();
@@ -124,7 +124,7 @@ impl Drop for _InsnCtxt {
124124
pub fn push_ctxt(s: &'static str) -> _InsnCtxt {
125125
debug!("new InsnCtxt: %s", s);
126126
unsafe {
127-
do local_data::local_data_modify(task_local_insn_key) |c| {
127+
do local_data::modify(task_local_insn_key) |c| {
128128
do c.map_consume |ctx| {
129129
let mut ctx = copy *ctx;
130130
ctx.push(s);

src/librustc/middle/trans/context.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -240,14 +240,14 @@ impl Drop for CrateContext {
240240

241241
fn task_local_llcx_key(_v: @ContextRef) {}
242242
pub fn task_llcx() -> ContextRef {
243-
let opt = unsafe { local_data::local_data_get(task_local_llcx_key) };
243+
let opt = unsafe { local_data::get(task_local_llcx_key, |k| k.map(|&k| *k)) };
244244
*opt.expect("task-local LLVMContextRef wasn't ever set!")
245245
}
246246

247247
unsafe fn set_task_llcx(c: ContextRef) {
248-
local_data::local_data_set(task_local_llcx_key, @c);
248+
local_data::set(task_local_llcx_key, @c);
249249
}
250250

251251
unsafe fn unset_task_llcx() {
252-
local_data::local_data_pop(task_local_llcx_key);
252+
local_data::pop(task_local_llcx_key);
253253
}

src/librusti/program.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ struct LocalVariable {
5858
}
5959

6060
type LocalCache = @mut HashMap<~str, @~[u8]>;
61-
fn tls_key(_k: @LocalCache) {}
61+
fn tls_key(_k: LocalCache) {}
6262

6363
impl Program {
6464
pub fn new() -> Program {
@@ -132,7 +132,7 @@ impl Program {
132132
");
133133

134134
let key: sys::Closure = unsafe {
135-
let tls_key: &'static fn(@LocalCache) = tls_key;
135+
let tls_key: &'static fn(LocalCache) = tls_key;
136136
cast::transmute(tls_key)
137137
};
138138
// First, get a handle to the tls map which stores all the local
@@ -144,7 +144,7 @@ impl Program {
144144
let key = ::std::sys::Closure{ code: %? as *(),
145145
env: ::std::ptr::null() };
146146
let key = ::std::cast::transmute(key);
147-
*::std::local_data::local_data_get(key).unwrap()
147+
::std::local_data::get(key, |k| k.map(|&x| *x)).unwrap()
148148
};\n", key.code as uint));
149149

150150
// Using this __tls_map handle, deserialize each variable binding that
@@ -227,7 +227,7 @@ impl Program {
227227
map.insert(copy *name, @copy value.data);
228228
}
229229
unsafe {
230-
local_data::local_data_set(tls_key, @map);
230+
local_data::set(tls_key, map);
231231
}
232232
}
233233

@@ -236,7 +236,7 @@ impl Program {
236236
/// it updates this cache with the new values of each local variable.
237237
pub fn consume_cache(&mut self) {
238238
let map = unsafe {
239-
local_data::local_data_pop(tls_key).expect("tls is empty")
239+
local_data::pop(tls_key).expect("tls is empty")
240240
};
241241
do map.consume |name, value| {
242242
match self.local_vars.find_mut(&name) {

src/libstd/condition.rs

+8-9
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212

1313
#[allow(missing_doc)];
1414

15-
use local_data::{local_data_pop, local_data_set};
1615
use local_data;
1716
use prelude::*;
1817

@@ -26,14 +25,14 @@ pub struct Handler<T, U> {
2625

2726
pub struct Condition<'self, T, U> {
2827
name: &'static str,
29-
key: local_data::LocalDataKey<'self, Handler<T, U>>
28+
key: local_data::Key<'self, @Handler<T, U>>
3029
}
3130

3231
impl<'self, T, U> Condition<'self, T, U> {
3332
pub fn trap(&'self self, h: &'self fn(T) -> U) -> Trap<'self, T, U> {
3433
unsafe {
3534
let p : *RustClosure = ::cast::transmute(&h);
36-
let prev = local_data::local_data_get(self.key);
35+
let prev = local_data::get(self.key, |k| k.map(|&x| *x));
3736
let h = @Handler { handle: *p, prev: prev };
3837
Trap { cond: self, handler: h }
3938
}
@@ -46,7 +45,7 @@ impl<'self, T, U> Condition<'self, T, U> {
4645

4746
pub fn raise_default(&self, t: T, default: &fn() -> U) -> U {
4847
unsafe {
49-
match local_data_pop(self.key) {
48+
match local_data::pop(self.key) {
5049
None => {
5150
debug!("Condition.raise: found no handler");
5251
default()
@@ -55,12 +54,12 @@ impl<'self, T, U> Condition<'self, T, U> {
5554
debug!("Condition.raise: found handler");
5655
match handler.prev {
5756
None => {}
58-
Some(hp) => local_data_set(self.key, hp)
57+
Some(hp) => local_data::set(self.key, hp)
5958
}
6059
let handle : &fn(T) -> U =
6160
::cast::transmute(handler.handle);
6261
let u = handle(t);
63-
local_data_set(self.key, handler);
62+
local_data::set(self.key, handler);
6463
u
6564
}
6665
}
@@ -78,7 +77,7 @@ impl<'self, T, U> Trap<'self, T, U> {
7877
unsafe {
7978
let _g = Guard { cond: self.cond };
8079
debug!("Trap: pushing handler to TLS");
81-
local_data_set(self.cond.key, self.handler);
80+
local_data::set(self.cond.key, self.handler);
8281
inner()
8382
}
8483
}
@@ -93,12 +92,12 @@ impl<'self, T, U> Drop for Guard<'self, T, U> {
9392
fn drop(&self) {
9493
unsafe {
9594
debug!("Guard: popping handler from TLS");
96-
let curr = local_data_pop(self.cond.key);
95+
let curr = local_data::pop(self.cond.key);
9796
match curr {
9897
None => {}
9998
Some(h) => match h.prev {
10099
None => {}
101-
Some(hp) => local_data_set(self.cond.key, hp)
100+
Some(hp) => local_data::set(self.cond.key, hp)
102101
}
103102
}
104103
}

0 commit comments

Comments
 (0)