Skip to content

Commit 4d9aebc

Browse files
committed
---
yaml --- r: 42683 b: refs/heads/try c: 7ff7489 h: refs/heads/master i: 42681: bf82485 42679: 58af19b v: v3
1 parent dd30205 commit 4d9aebc

30 files changed

+1193
-1691
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: 19dfec2aaf746535de1521f68421f9980dbf25de
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 2f46b763da2c098913884f101b6d71d69af41b49
5-
refs/heads/try: 1ef83945c1d76c9f2b9b0d087ceac65963087be7
5+
refs/heads/try: 7ff7489dc62bdcc0dbd507c52cba90d47cfdd129
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: a810c03263670238bccd64cabb12a23a46e3a278

branches/try/AUTHORS.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Brian Leibig <[email protected]>
3434
Chris Double <[email protected]>
3535
Chris Peterson <[email protected]>
3636
Chris Pressey <[email protected]>
37+
Cody Schroeder <[email protected]>
3738
Damian Gryski <[email protected]>
3839
Damien Grassart <[email protected]>
3940
Damien Schoof <[email protected]>

branches/try/src/libcore/os.rs

Lines changed: 136 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -141,101 +141,169 @@ pub mod win32 {
141141
}
142142
}
143143

144-
/*
145-
Accessing environment variables is not generally threadsafe.
146-
This uses a per-runtime lock to serialize access.
147-
XXX: It would probably be appropriate to make this a real global
148-
*/
149-
fn with_env_lock<T>(f: &fn() -> T) -> T {
150-
use private::global::global_data_clone_create;
151-
use private::{Exclusive, exclusive};
152-
153-
struct SharedValue(());
154-
type ValueMutex = Exclusive<SharedValue>;
155-
fn key(_: ValueMutex) { }
156-
157-
unsafe {
158-
let lock: ValueMutex = global_data_clone_create(key, || {
159-
~exclusive(SharedValue(()))
160-
});
144+
pub fn getenv(n: &str) -> Option<~str> {
145+
global_env::getenv(n)
146+
}
161147

162-
lock.with_imm(|_| f() )
163-
}
148+
pub fn setenv(n: &str, v: &str) {
149+
global_env::setenv(n, v)
164150
}
165151

166152
pub fn env() -> ~[(~str,~str)] {
153+
global_env::env()
154+
}
155+
156+
mod global_env {
157+
//! Internal module for serializing access to getenv/setenv
158+
use either;
159+
use libc;
160+
use oldcomm;
161+
use option::Option;
162+
use private;
163+
use str;
164+
use task;
165+
167166
extern mod rustrt {
168-
unsafe fn rust_env_pairs() -> ~[~str];
167+
unsafe fn rust_global_env_chan_ptr() -> *libc::uintptr_t;
169168
}
170169

171-
unsafe {
172-
do with_env_lock {
173-
let mut pairs = ~[];
174-
for vec::each(rustrt::rust_env_pairs()) |p| {
175-
let vs = str::splitn_char(*p, '=', 1u);
176-
assert vec::len(vs) == 2u;
177-
pairs.push((copy vs[0], copy vs[1]));
178-
}
179-
move pairs
170+
enum Msg {
171+
MsgGetEnv(~str, oldcomm::Chan<Option<~str>>),
172+
MsgSetEnv(~str, ~str, oldcomm::Chan<()>),
173+
MsgEnv(oldcomm::Chan<~[(~str,~str)]>)
174+
}
175+
176+
pub fn getenv(n: &str) -> Option<~str> {
177+
let env_ch = get_global_env_chan();
178+
let po = oldcomm::Port();
179+
oldcomm::send(env_ch, MsgGetEnv(str::from_slice(n),
180+
oldcomm::Chan(&po)));
181+
oldcomm::recv(po)
182+
}
183+
184+
pub fn setenv(n: &str, v: &str) {
185+
let env_ch = get_global_env_chan();
186+
let po = oldcomm::Port();
187+
oldcomm::send(env_ch, MsgSetEnv(str::from_slice(n),
188+
str::from_slice(v),
189+
oldcomm::Chan(&po)));
190+
oldcomm::recv(po)
191+
}
192+
193+
pub fn env() -> ~[(~str,~str)] {
194+
let env_ch = get_global_env_chan();
195+
let po = oldcomm::Port();
196+
oldcomm::send(env_ch, MsgEnv(oldcomm::Chan(&po)));
197+
oldcomm::recv(po)
198+
}
199+
200+
fn get_global_env_chan() -> oldcomm::Chan<Msg> {
201+
unsafe {
202+
let global_ptr = rustrt::rust_global_env_chan_ptr();
203+
private::chan_from_global_ptr(global_ptr, || {
204+
// FIXME (#2621): This would be a good place to use a very
205+
// small foreign stack
206+
task::task().sched_mode(task::SingleThreaded).unlinked()
207+
}, global_env_task)
180208
}
181209
}
182-
}
183210

184-
#[cfg(unix)]
185-
pub fn getenv(n: &str) -> Option<~str> {
186-
unsafe {
187-
do with_env_lock {
188-
let s = str::as_c_str(n, |s| libc::getenv(s));
189-
if ptr::null::<u8>() == cast::reinterpret_cast(&s) {
190-
option::None::<~str>
191-
} else {
192-
let s = cast::reinterpret_cast(&s);
193-
option::Some::<~str>(str::raw::from_buf(s))
211+
fn global_env_task(msg_po: oldcomm::Port<Msg>) {
212+
unsafe {
213+
do private::weaken_task |weak_po| {
214+
loop {
215+
match oldcomm::select2(msg_po, weak_po) {
216+
either::Left(MsgGetEnv(ref n, resp_ch)) => {
217+
oldcomm::send(resp_ch, impl_::getenv(*n))
218+
}
219+
either::Left(MsgSetEnv(ref n, ref v, resp_ch)) => {
220+
oldcomm::send(resp_ch, impl_::setenv(*n, *v))
221+
}
222+
either::Left(MsgEnv(resp_ch)) => {
223+
oldcomm::send(resp_ch, impl_::env())
224+
}
225+
either::Right(_) => break
226+
}
227+
}
194228
}
195229
}
196230
}
197-
}
198231

199-
#[cfg(windows)]
200-
pub fn getenv(n: &str) -> Option<~str> {
201-
unsafe {
202-
do with_env_lock {
203-
use os::win32::{as_utf16_p, fill_utf16_buf_and_decode};
204-
do as_utf16_p(n) |u| {
205-
do fill_utf16_buf_and_decode() |buf, sz| {
206-
libc::GetEnvironmentVariableW(u, buf, sz)
232+
mod impl_ {
233+
use cast;
234+
use libc;
235+
use option::Option;
236+
use option;
237+
use ptr;
238+
use str;
239+
use vec;
240+
241+
extern mod rustrt {
242+
unsafe fn rust_env_pairs() -> ~[~str];
243+
}
244+
245+
pub fn env() -> ~[(~str,~str)] {
246+
unsafe {
247+
let mut pairs = ~[];
248+
for vec::each(rustrt::rust_env_pairs()) |p| {
249+
let vs = str::splitn_char(*p, '=', 1u);
250+
assert vec::len(vs) == 2u;
251+
pairs.push((copy vs[0], copy vs[1]));
207252
}
253+
move pairs
208254
}
209255
}
210-
}
211-
}
212256

257+
#[cfg(unix)]
258+
pub fn getenv(n: &str) -> Option<~str> {
259+
unsafe {
260+
let s = str::as_c_str(n, |s| libc::getenv(s));
261+
return if ptr::null::<u8>() == cast::reinterpret_cast(&s) {
262+
option::None::<~str>
263+
} else {
264+
let s = cast::reinterpret_cast(&s);
265+
option::Some::<~str>(str::raw::from_buf(s))
266+
};
267+
}
268+
}
213269

214-
#[cfg(unix)]
215-
pub fn setenv(n: &str, v: &str) {
216-
unsafe {
217-
do with_env_lock {
218-
do str::as_c_str(n) |nbuf| {
219-
do str::as_c_str(v) |vbuf| {
220-
libc::funcs::posix01::unistd::setenv(nbuf, vbuf, 1);
270+
#[cfg(windows)]
271+
pub fn getenv(n: &str) -> Option<~str> {
272+
unsafe {
273+
use os::win32::{as_utf16_p, fill_utf16_buf_and_decode};
274+
do as_utf16_p(n) |u| {
275+
do fill_utf16_buf_and_decode() |buf, sz| {
276+
libc::GetEnvironmentVariableW(u, buf, sz)
277+
}
221278
}
222279
}
223280
}
224-
}
225-
}
226281

227282

228-
#[cfg(windows)]
229-
pub fn setenv(n: &str, v: &str) {
230-
unsafe {
231-
do with_env_lock {
232-
use os::win32::as_utf16_p;
233-
do as_utf16_p(n) |nbuf| {
234-
do as_utf16_p(v) |vbuf| {
235-
libc::SetEnvironmentVariableW(nbuf, vbuf);
283+
#[cfg(unix)]
284+
pub fn setenv(n: &str, v: &str) {
285+
unsafe {
286+
do str::as_c_str(n) |nbuf| {
287+
do str::as_c_str(v) |vbuf| {
288+
libc::funcs::posix01::unistd::setenv(nbuf, vbuf, 1);
289+
}
236290
}
237291
}
238292
}
293+
294+
295+
#[cfg(windows)]
296+
pub fn setenv(n: &str, v: &str) {
297+
unsafe {
298+
use os::win32::as_utf16_p;
299+
do as_utf16_p(n) |nbuf| {
300+
do as_utf16_p(v) |vbuf| {
301+
libc::SetEnvironmentVariableW(nbuf, vbuf);
302+
}
303+
}
304+
}
305+
}
306+
239307
}
240308
}
241309

branches/try/src/libcore/pipes.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,16 +1286,6 @@ pub fn oneshot<T: Owned>() -> (PortOne<T>, ChanOne<T>) {
12861286
(port, chan)
12871287
}
12881288

1289-
impl<T: Owned> PortOne<T> {
1290-
fn recv(self) -> T { recv_one(self) }
1291-
fn try_recv(self) -> Option<T> { try_recv_one(self) }
1292-
}
1293-
1294-
impl<T: Owned> ChanOne<T> {
1295-
fn send(self, data: T) { send_one(self, data) }
1296-
fn try_send(self, data: T) -> bool { try_send_one(self, data) }
1297-
}
1298-
12991289
/**
13001290
* Receive a message from a oneshot pipe, failing if the connection was
13011291
* closed.

0 commit comments

Comments
 (0)