Skip to content

Commit 3d92041

Browse files
committed
---
yaml --- r: 96922 b: refs/heads/dist-snap c: f5d9b2c h: refs/heads/master v: v3
1 parent 5aa3b5c commit 3d92041

File tree

4 files changed

+140
-18
lines changed

4 files changed

+140
-18
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ refs/heads/try: c274a6888410ce3e357e014568b43310ed787d36
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c
9-
refs/heads/dist-snap: 018d60509c04cdebdf8b0d9e2b58f2604538e516
9+
refs/heads/dist-snap: f5d9b2ca6d9a360112f06b3044897c22736c52b8
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503
1212
refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0

branches/dist-snap/src/libnative/io/file.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -899,8 +899,7 @@ pub fn utime(p: &CString, atime: u64, mtime: u64) -> IoResult<()> {
899899

900900
#[cfg(test)]
901901
mod tests {
902-
use std::io::native::file::{CFile, FileDesc};
903-
use std::io::fs;
902+
use super::{CFile, FileDesc};
904903
use std::io;
905904
use std::libc;
906905
use std::os;

branches/dist-snap/src/libnative/lib.rs

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,38 +24,64 @@
2424
#[crate_type = "rlib"];
2525
#[crate_type = "dylib"];
2626

27+
#[cfg(stage0, test)] extern mod green;
28+
2729
// NB this crate explicitly does *not* allow glob imports, please seriously
28-
// consider whether they're needed before adding that feature here.
30+
// consider whether they're needed before adding that feature here (the
31+
// answer is that you don't need them)
2932

30-
use std::cast;
3133
use std::os;
3234
use std::rt;
33-
use std::task::try;
3435

3536
pub mod io;
3637
pub mod task;
3738

39+
3840
// XXX: this should not exist here
39-
#[cfg(stage0)]
41+
#[cfg(stage0, notready)]
4042
#[lang = "start"]
41-
pub fn start(main: *u8, argc: int, argv: **u8) -> int {
42-
rt::init(argc, argv);
43+
pub fn lang_start(main: *u8, argc: int, argv: **u8) -> int {
44+
use std::cast;
45+
use std::task::try;
4346

44-
// Bootstrap ourselves by installing a local Task and then immediately
45-
// spawning a thread to run 'main'. Always spawn a new thread for main so
46-
// the stack size of 'main' is known (and the bounds can be set
47-
// appropriately).
48-
//
49-
// Once the main task has completed, then we wait for everyone else to exit.
50-
task::run(task::new(), proc() {
47+
do start(argc, argv) {
48+
// Instead of invoking main directly on this thread, invoke it on
49+
// another spawned thread that we are guaranteed to know the size of the
50+
// stack of. Currently, we do not have a method of figuring out the size
51+
// of the main thread's stack, so for stack overflow detection to work
52+
// we must spawn the task in a subtask which we know the stack size of.
5153
let main: extern "Rust" fn() = unsafe { cast::transmute(main) };
5254
match do try { main() } {
5355
Ok(()) => { os::set_exit_status(0); }
5456
Err(..) => { os::set_exit_status(rt::DEFAULT_ERROR_CODE); }
5557
}
56-
});
57-
task::wait_for_completion();
58+
}
59+
}
5860

61+
/// Executes the given procedure after initializing the runtime with the given
62+
/// argc/argv.
63+
///
64+
/// This procedure is guaranteed to run on the thread calling this function, but
65+
/// the stack bounds for this rust task will *not* be set. Care must be taken
66+
/// for this function to not overflow its stack.
67+
///
68+
/// This function will only return once *all* native threads in the system have
69+
/// exited.
70+
pub fn start(argc: int, argv: **u8, main: proc()) -> int {
71+
rt::init(argc, argv);
72+
let exit_code = run(main);
5973
unsafe { rt::cleanup(); }
74+
return exit_code;
75+
}
76+
77+
/// Executes a procedure on the current thread in a Rust task context.
78+
///
79+
/// This function has all of the same details as `start` except for a different
80+
/// number of arguments.
81+
pub fn run(main: proc()) -> int {
82+
// Create a task, run the procedure in it, and then wait for everything.
83+
task::run(task::new(), main);
84+
task::wait_for_completion();
85+
6086
os::get_exit_status()
6187
}

branches/dist-snap/src/libnative/task.rs

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,3 +260,100 @@ impl Drop for Ops {
260260
unsafe { self.lock.destroy() }
261261
}
262262
}
263+
264+
#[cfg(test)]
265+
mod tests {
266+
use std::rt::Runtime;
267+
use std::rt::local::Local;
268+
use std::rt::task::Task;
269+
use std::task;
270+
use super::{spawn, spawn_opts, Ops};
271+
272+
#[test]
273+
fn smoke() {
274+
let (p, c) = Chan::new();
275+
do spawn {
276+
c.send(());
277+
}
278+
p.recv();
279+
}
280+
281+
#[test]
282+
fn smoke_fail() {
283+
let (p, c) = Chan::<()>::new();
284+
do spawn {
285+
let _c = c;
286+
fail!()
287+
}
288+
assert_eq!(p.recv_opt(), None);
289+
}
290+
291+
#[test]
292+
fn smoke_opts() {
293+
let mut opts = task::default_task_opts();
294+
opts.name = Some(SendStrStatic("test"));
295+
opts.stack_size = Some(20 * 4096);
296+
let (p, c) = Chan::new();
297+
opts.notify_chan = Some(c);
298+
spawn_opts(opts, proc() {});
299+
assert!(p.recv().is_ok());
300+
}
301+
302+
#[test]
303+
fn smoke_opts_fail() {
304+
let mut opts = task::default_task_opts();
305+
let (p, c) = Chan::new();
306+
opts.notify_chan = Some(c);
307+
spawn_opts(opts, proc() { fail!() });
308+
assert!(p.recv().is_err());
309+
}
310+
311+
#[test]
312+
fn yield_test() {
313+
let (p, c) = Chan::new();
314+
do spawn {
315+
10.times(task::deschedule);
316+
c.send(());
317+
}
318+
p.recv();
319+
}
320+
321+
#[test]
322+
fn spawn_children() {
323+
let (p, c) = Chan::new();
324+
do spawn {
325+
let (p, c2) = Chan::new();
326+
do spawn {
327+
let (p, c3) = Chan::new();
328+
do spawn {
329+
c3.send(());
330+
}
331+
p.recv();
332+
c2.send(());
333+
}
334+
p.recv();
335+
c.send(());
336+
}
337+
p.recv();
338+
}
339+
340+
#[test]
341+
fn spawn_inherits() {
342+
let (p, c) = Chan::new();
343+
do spawn {
344+
let c = c;
345+
do spawn {
346+
let mut task: ~Task = Local::take();
347+
match task.maybe_take_runtime::<Ops>() {
348+
Some(ops) => {
349+
task.put_runtime(ops as ~Runtime);
350+
}
351+
None => fail!(),
352+
}
353+
Local::put(task);
354+
c.send(());
355+
}
356+
}
357+
p.recv();
358+
}
359+
}

0 commit comments

Comments
 (0)