Skip to content

Commit 4341e50

Browse files
committed
Add safe versions of spawn using bare functions
Currently they just wrap the unsafe versions. Will need to be rewritten eventually. Issue #1022
1 parent 034408c commit 4341e50

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

src/lib/task.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ export task_result;
2121
export tr_success;
2222
export tr_failure;
2323
export get_task_id;
24+
export spawn2;
25+
export spawn_notify2;
26+
export spawn_joinable2;
2427

2528
native "rust" mod rustrt {
2629
fn task_sleep(time_in_us: uint);
@@ -93,6 +96,47 @@ fn unpin() { rustrt::unpin_task(); }
9396

9497
fn set_min_stack(stack_size: uint) { rustrt::set_min_stack(stack_size); }
9598

99+
fn spawn2<~T>(-data: T, f: fn#(T)) -> task {
100+
spawn_inner2(data, f, none)
101+
}
102+
103+
fn spawn_notify2<~T>(-data: T, f: fn#(T),
104+
notify: comm::chan<task_notification>) -> task {
105+
spawn_inner2(data, f, some(notify))
106+
}
107+
108+
fn spawn_joinable2<~T>(-data: T, f: fn#(T)) -> joinable_task {
109+
let p = comm::port::<task_notification>();
110+
let id = spawn_notify2(data, f, comm::chan::<task_notification>(p));
111+
ret (id, p);
112+
}
113+
114+
// FIXME: To transition from the unsafe spawn that spawns a shared closure to
115+
// the safe spawn that spawns a bare function we're going to write
116+
// barefunc-spawn on top of unsafe-spawn. Sadly, bind does not work reliably
117+
// enough to suite our needs (#1034, probably others yet to be discovered), so
118+
// we're going to copy the bootstrap data into a unique pointer, cast it to an
119+
// unsafe pointer then wrap up the bare function and the unsafe pointer in a
120+
// shared closure to spawn.
121+
//
122+
// After the transition this should all be rewritten.
123+
124+
fn spawn_inner2<~T>(-data: T, f: fn#(T),
125+
notify: option<comm::chan<task_notification>>)
126+
-> task_id {
127+
128+
fn wrapper<~T>(-data: *u8, f: fn#(T)) {
129+
let data: ~T = unsafe::reinterpret_cast(data);
130+
f(*data);
131+
}
132+
133+
let data = ~data;
134+
let dataptr: *u8 = unsafe::reinterpret_cast(data);
135+
unsafe::leak(data);
136+
let wrapped = bind wrapper(dataptr, f);
137+
ret spawn_inner(wrapped, notify);
138+
}
139+
96140
fn spawn(-thunk: fn()) -> task { spawn_inner(thunk, none) }
97141

98142
fn spawn_notify(-thunk: fn(), notify: comm::chan<task_notification>) -> task {

0 commit comments

Comments
 (0)