Skip to content

Commit 20bfd1e

Browse files
committed
---
yaml --- r: 142635 b: refs/heads/try2 c: 1b7c996 h: refs/heads/master i: 142633: d469be9 142631: dff7057 v: v3
1 parent d8fe679 commit 20bfd1e

File tree

6 files changed

+177
-12
lines changed

6 files changed

+177
-12
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: 7a9a6e45911636eae3ec4e1c111bc0e120601a5a
8+
refs/heads/try2: 1b7c99655f300aa0b8ba216cd2029dc588c3ef88
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/libstd/os.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ use option::{Some, None};
4040
use os;
4141
use prelude::*;
4242
use ptr;
43+
use rt;
44+
use rt::TaskContext;
4345
use str;
4446
use uint;
4547
use unstable::finally::Finally;
@@ -1167,10 +1169,17 @@ pub fn real_args() -> ~[~str] {
11671169
#[cfg(target_os = "android")]
11681170
#[cfg(target_os = "freebsd")]
11691171
pub fn real_args() -> ~[~str] {
1170-
unsafe {
1171-
let argc = rustrt::rust_get_argc();
1172-
let argv = rustrt::rust_get_argv();
1173-
load_argc_and_argv(argc, argv)
1172+
if rt::context() == TaskContext {
1173+
match rt::args::clone() {
1174+
Some(args) => args,
1175+
None => fail!("process arguments not initialized")
1176+
}
1177+
} else {
1178+
unsafe {
1179+
let argc = rustrt::rust_get_argc();
1180+
let argv = rustrt::rust_get_argv();
1181+
load_argc_and_argv(argc, argv)
1182+
}
11741183
}
11751184
}
11761185

branches/try2/src/libstd/rt/args.rs

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//! Global storage for command line arguments
12+
//!
13+
//! The current incarnation of the Rust runtime expects for
14+
//! the processes `argc` and `argv` arguments to be stored
15+
//! in a globally-accessible location for use by the `os` module.
16+
//!
17+
//! XXX: Would be nice for this to not exist.
18+
//! XXX: This has a lot of C glue for lack of globals.
19+
20+
use libc;
21+
use option::{Option, Some, None};
22+
use str;
23+
use uint;
24+
use unstable::finally::Finally;
25+
use util;
26+
27+
/// One-time global initialization.
28+
pub unsafe fn init(argc: int, argv: **u8) {
29+
let args = load_argc_and_argv(argc, argv);
30+
put(args);
31+
}
32+
33+
/// One-time global cleanup.
34+
pub fn cleanup() {
35+
rtassert!(take().is_some());
36+
}
37+
38+
/// Take the global arguments from global storage.
39+
pub fn take() -> Option<~[~str]> {
40+
with_lock(|| unsafe {
41+
let ptr = get_global_ptr();
42+
let val = util::replace(&mut *ptr, None);
43+
val.map(|s: &~~[~str]| (**s).clone())
44+
})
45+
}
46+
47+
/// Give the global arguments to global storage.
48+
///
49+
/// It is an error if the arguments already exist.
50+
pub fn put(args: ~[~str]) {
51+
with_lock(|| unsafe {
52+
let ptr = get_global_ptr();
53+
rtassert!((*ptr).is_none());
54+
(*ptr) = Some(~args.clone());
55+
})
56+
}
57+
58+
/// Make a clone of the global arguments.
59+
pub fn clone() -> Option<~[~str]> {
60+
with_lock(|| unsafe {
61+
let ptr = get_global_ptr();
62+
(*ptr).map(|s: &~~[~str]| (**s).clone())
63+
})
64+
}
65+
66+
fn with_lock<T>(f: &fn() -> T) -> T {
67+
do (|| {
68+
unsafe {
69+
rust_take_global_args_lock();
70+
f()
71+
}
72+
}).finally {
73+
unsafe {
74+
rust_drop_global_args_lock();
75+
}
76+
}
77+
}
78+
79+
fn get_global_ptr() -> *mut Option<~~[~str]> {
80+
unsafe { rust_get_global_args_ptr() }
81+
}
82+
83+
// Copied from `os`.
84+
unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> ~[~str] {
85+
let mut args = ~[];
86+
for uint::range(0, argc as uint) |i| {
87+
args.push(str::raw::from_c_str(*(argv as **libc::c_char).offset(i)));
88+
}
89+
return args;
90+
}
91+
92+
extern {
93+
fn rust_take_global_args_lock();
94+
fn rust_drop_global_args_lock();
95+
fn rust_get_global_args_ptr() -> *mut Option<~~[~str]>;
96+
}
97+
98+
#[cfg(test)]
99+
mod tests {
100+
use option::{Some, None};
101+
use super::*;
102+
use unstable::finally::Finally;
103+
104+
#[test]
105+
fn smoke_test() {
106+
// Preserve the actual global state.
107+
let saved_value = take();
108+
109+
let expected = ~[~"happy", ~"today?"];
110+
111+
put(expected.clone());
112+
assert!(clone() == Some(expected.clone()));
113+
assert!(take() == Some(expected.clone()));
114+
assert!(take() == None);
115+
116+
do (|| {
117+
}).finally {
118+
// Restore the actual global state.
119+
match saved_value {
120+
Some(ref args) => put(args.clone()),
121+
None => ()
122+
}
123+
}
124+
}
125+
}

branches/try2/src/libstd/rt/mod.rs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@ pub mod metrics;
159159
/// Just stuff
160160
pub mod util;
161161

162+
// Global command line argument storage
163+
pub mod args;
164+
162165
/// Set up a default runtime configuration, given compiler-supplied arguments.
163166
///
164167
/// This is invoked by the `start` _language item_ (unstable::lang) to
@@ -173,20 +176,28 @@ pub mod util;
173176
/// # Return value
174177
///
175178
/// The return value is used as the process return code. 0 on success, 101 on error.
176-
pub fn start(_argc: int, _argv: **u8, crate_map: *u8, main: ~fn()) -> int {
179+
pub fn start(argc: int, argv: **u8, crate_map: *u8, main: ~fn()) -> int {
177180

178-
init(crate_map);
181+
init(argc, argv, crate_map);
179182
let exit_code = run(main);
180183
cleanup();
181184

182185
return exit_code;
183186
}
184187

185-
/// One-time runtime initialization. Currently all this does is set up logging
186-
/// based on the RUST_LOG environment variable.
187-
pub fn init(crate_map: *u8) {
188-
logging::init(crate_map);
189-
unsafe { rust_update_gc_metadata(crate_map) }
188+
/// One-time runtime initialization.
189+
///
190+
/// Initializes global state, including frobbing
191+
/// the crate's logging flags, registering GC
192+
/// metadata, and storing the process arguments.
193+
pub fn init(argc: int, argv: **u8, crate_map: *u8) {
194+
// XXX: Derefing these pointers is not safe.
195+
// Need to propagate the unsafety to `start`.
196+
unsafe {
197+
args::init(argc, argv);
198+
logging::init(crate_map);
199+
rust_update_gc_metadata(crate_map);
200+
}
190201

191202
extern {
192203
fn rust_update_gc_metadata(crate_map: *u8);
@@ -195,6 +206,7 @@ pub fn init(crate_map: *u8) {
195206

196207
/// One-time runtime cleanup.
197208
pub fn cleanup() {
209+
args::cleanup();
198210
global_heap::cleanup();
199211
}
200212

branches/try2/src/rt/rust_builtin.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,24 @@ rust_get_num_cpus() {
932932
return get_num_cpus();
933933
}
934934

935+
static lock_and_signal global_args_lock;
936+
static uintptr_t global_args_ptr = 0;
937+
938+
extern "C" CDECL void
939+
rust_take_global_args_lock() {
940+
global_args_lock.lock();
941+
}
942+
943+
extern "C" CDECL void
944+
rust_drop_global_args_lock() {
945+
global_args_lock.unlock();
946+
}
947+
948+
extern "C" CDECL uintptr_t*
949+
rust_get_global_args_ptr() {
950+
return &global_args_ptr;
951+
}
952+
935953
//
936954
// Local Variables:
937955
// mode: C++

branches/try2/src/rt/rustrt.def.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,3 +242,4 @@ rust_drop_env_lock
242242
rust_update_log_settings
243243
rust_running_on_valgrind
244244
rust_get_num_cpus
245+
rust_get_global_args_ptr

0 commit comments

Comments
 (0)