Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
aec67c2e
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
aec67c2e
编写于
12月 31, 2014
作者:
A
Alex Crichton
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Revert "std: Re-enable at_exit()"
This reverts commit
9e224c2b
. Conflicts: src/libstd/sys/windows/os.rs
上级
582cba18
变更
39
隐藏空白更改
内联
并排
Showing
39 changed file
with
245 addition
and
191 deletion
+245
-191
src/liblog/lib.rs
src/liblog/lib.rs
+8
-26
src/libstd/io/stdio.rs
src/libstd/io/stdio.rs
+24
-19
src/libstd/lib.rs
src/libstd/lib.rs
+2
-2
src/libstd/rt/at_exit_imp.rs
src/libstd/rt/at_exit_imp.rs
+1
-3
src/libstd/rt/mod.rs
src/libstd/rt/mod.rs
+18
-7
src/libstd/rt/unwind.rs
src/libstd/rt/unwind.rs
+4
-13
src/libstd/sys/common/helper_thread.rs
src/libstd/sys/common/helper_thread.rs
+5
-26
src/libstd/sys/common/mod.rs
src/libstd/sys/common/mod.rs
+1
-1
src/libstd/sys/common/mutex.rs
src/libstd/sys/common/mutex.rs
+0
-1
src/libstd/sys/common/net.rs
src/libstd/sys/common/net.rs
+1
-5
src/libstd/sys/common/rwlock.rs
src/libstd/sys/common/rwlock.rs
+0
-1
src/libstd/sys/common/stack.rs
src/libstd/sys/common/stack.rs
+31
-0
src/libstd/sys/common/thread_info.rs
src/libstd/sys/common/thread_info.rs
+7
-3
src/libstd/sys/common/thread_local.rs
src/libstd/sys/common/thread_local.rs
+4
-1
src/libstd/sys/unix/backtrace.rs
src/libstd/sys/unix/backtrace.rs
+8
-4
src/libstd/sys/unix/mod.rs
src/libstd/sys/unix/mod.rs
+16
-0
src/libstd/sys/unix/mutex.rs
src/libstd/sys/unix/mutex.rs
+1
-1
src/libstd/sys/unix/os.rs
src/libstd/sys/unix/os.rs
+5
-4
src/libstd/sys/unix/pipe.rs
src/libstd/sys/unix/pipe.rs
+1
-1
src/libstd/sys/unix/process.rs
src/libstd/sys/unix/process.rs
+4
-11
src/libstd/sys/unix/rwlock.rs
src/libstd/sys/unix/rwlock.rs
+0
-1
src/libstd/sys/unix/stack_overflow.rs
src/libstd/sys/unix/stack_overflow.rs
+1
-0
src/libstd/sys/unix/tcp.rs
src/libstd/sys/unix/tcp.rs
+4
-0
src/libstd/sys/unix/timer.rs
src/libstd/sys/unix/timer.rs
+2
-9
src/libstd/sys/unix/tty.rs
src/libstd/sys/unix/tty.rs
+1
-0
src/libstd/sys/windows/backtrace.rs
src/libstd/sys/windows/backtrace.rs
+14
-17
src/libstd/sys/windows/c.rs
src/libstd/sys/windows/c.rs
+1
-0
src/libstd/sys/windows/fs.rs
src/libstd/sys/windows/fs.rs
+8
-4
src/libstd/sys/windows/mod.rs
src/libstd/sys/windows/mod.rs
+24
-0
src/libstd/sys/windows/os.rs
src/libstd/sys/windows/os.rs
+1
-0
src/libstd/sys/windows/pipe.rs
src/libstd/sys/windows/pipe.rs
+4
-4
src/libstd/sys/windows/process.rs
src/libstd/sys/windows/process.rs
+9
-6
src/libstd/sys/windows/stack_overflow.rs
src/libstd/sys/windows/stack_overflow.rs
+9
-1
src/libstd/sys/windows/tcp.rs
src/libstd/sys/windows/tcp.rs
+7
-2
src/libstd/sys/windows/thread.rs
src/libstd/sys/windows/thread.rs
+2
-0
src/libstd/sys/windows/thread_local.rs
src/libstd/sys/windows/thread_local.rs
+2
-9
src/libstd/sys/windows/timer.rs
src/libstd/sys/windows/timer.rs
+4
-3
src/libstd/sys/windows/tty.rs
src/libstd/sys/windows/tty.rs
+5
-3
src/libstd/thread.rs
src/libstd/thread.rs
+6
-3
未找到文件。
src/liblog/lib.rs
浏览文件 @
aec67c2e
...
...
@@ -177,7 +177,7 @@
use
std
::
os
;
use
std
::
rt
;
use
std
::
slice
;
use
std
::
sync
::{
Once
,
ONCE_INIT
,
StaticMutex
,
MUTEX_INIT
};
use
std
::
sync
::{
Once
,
ONCE_INIT
};
use
regex
::
Regex
;
...
...
@@ -193,8 +193,6 @@
/// The default logging level of a crate if no other is specified.
const
DEFAULT_LOG_LEVEL
:
u32
=
1
;
static
LOCK
:
StaticMutex
=
MUTEX_INIT
;
/// An unsafe constant that is the maximum logging level of any module
/// specified. This is the first line of defense to determining whether a
/// logging statement should be run.
...
...
@@ -281,18 +279,9 @@ fn drop(&mut self) {
pub
fn
log
(
level
:
u32
,
loc
:
&
'static
LogLocation
,
args
:
fmt
::
Arguments
)
{
// Test the literal string from args against the current filter, if there
// is one.
unsafe
{
let
_
g
=
LOCK
.lock
();
match
FILTER
as
uint
{
0
=>
{}
1
=>
panic!
(
"cannot log after main thread has exited"
),
n
=>
{
let
filter
=
mem
::
transmute
::
<
_
,
&
Regex
>
(
n
);
if
!
filter
.is_match
(
args
.to_string
()
.as_slice
())
{
return
}
}
}
match
unsafe
{
FILTER
.as_ref
()
}
{
Some
(
filter
)
if
!
filter
.is_match
(
args
.to_string
()[])
=>
return
,
_
=>
{}
}
// Completely remove the local logger from TLS in case anyone attempts to
...
...
@@ -374,15 +363,9 @@ pub fn mod_enabled(level: u32, module: &str) -> bool {
// This assertion should never get tripped unless we're in an at_exit
// handler after logging has been torn down and a logging attempt was made.
assert
!
(
unsafe
{
!
DIRECTIVES
.is_null
()
});
let
_
g
=
LOCK
.lock
();
unsafe
{
assert
!
(
DIRECTIVES
as
uint
!=
0
);
assert
!
(
DIRECTIVES
as
uint
!=
1
,
"cannot log after the main thread has exited"
);
enabled
(
level
,
module
,
(
*
DIRECTIVES
)
.iter
())
}
enabled
(
level
,
module
,
unsafe
{
(
*
DIRECTIVES
)
.iter
()
})
}
fn
enabled
(
level
:
u32
,
...
...
@@ -438,15 +421,14 @@ fn init() {
// Schedule the cleanup for the globals for when the runtime exits.
rt
::
at_exit
(
move
|:|
{
let
_
g
=
LOCK
.lock
();
assert
!
(
!
DIRECTIVES
.is_null
());
let
_
directives
:
Box
<
Vec
<
directive
::
LogDirective
>>
=
mem
::
transmute
(
DIRECTIVES
);
DIRECTIVES
=
1
as
*
const
Vec
<
directive
::
LogDirective
>
;
DIRECTIVES
=
0
as
*
const
Vec
<
directive
::
LogDirective
>
;
if
!
FILTER
.is_null
()
{
let
_
filter
:
Box
<
Regex
>
=
mem
::
transmute
(
FILTER
);
FILTER
=
1
as
*
const
_
;
FILTER
=
0
as
*
const
_
;
}
});
}
...
...
src/libstd/io/stdio.rs
浏览文件 @
aec67c2e
...
...
@@ -26,19 +26,29 @@
//! ```
use
self
::
StdSource
::
*
;
use
prelude
::
*
;
use
boxed
::
Box
;
use
cell
::
RefCell
;
use
clone
::
Clone
;
use
failure
::
LOCAL_STDERR
;
use
fmt
;
use
io
::{
IoResult
,
IoError
,
OtherIoError
};
use
io
::{
standard_error
,
EndOfFile
,
LineBufferedWriter
,
BufferedReader
};
use
io
::{
Reader
,
Writer
,
IoResult
,
IoError
,
OtherIoError
,
Buffer
,
standard_error
,
EndOfFile
,
LineBufferedWriter
,
BufferedReader
};
use
kinds
::{
Sync
,
Send
};
use
libc
;
use
mem
;
use
option
::
Option
;
use
option
::
Option
::{
Some
,
None
};
use
ops
::{
Deref
,
DerefMut
,
FnOnce
};
use
result
::
Result
::{
Ok
,
Err
};
use
rt
;
use
slice
::
SliceExt
;
use
str
::
StrExt
;
use
string
::
String
;
use
sys
::{
fs
,
tty
};
use
sync
::{
Arc
,
Mutex
,
MutexGuard
,
StaticMutex
,
MUTEX
_INIT
};
use
sync
::{
Arc
,
Mutex
,
MutexGuard
,
Once
,
ONCE
_INIT
};
use
uint
;
use
vec
::
Vec
;
// And so begins the tale of acquiring a uv handle to a stdio stream on all
// platforms in all situations. Our story begins by splitting the world into two
...
...
@@ -205,15 +215,14 @@ fn read_be_uint_n(&mut self, nbytes: uint) -> IoResult<u64> {
pub
fn
stdin
()
->
StdinReader
{
// We're following the same strategy as kimundi's lazy_static library
static
mut
STDIN
:
*
const
StdinReader
=
0
as
*
const
StdinReader
;
static
LOCK
:
StaticMutex
=
MUTEX
_INIT
;
static
ONCE
:
Once
=
ONCE
_INIT
;
unsafe
{
let
_
g
=
LOCK
.lock
();
if
STDIN
as
uint
==
0
{
// The default buffer capacity is 64k, but apparently windows
// doesn't like 64k reads on stdin. See #13304 for details, but the
// idea is that on windows we use a slightly smaller buffer that's
// been seen to be acceptable.
ONCE
.doit
(||
{
// The default buffer capacity is 64k, but apparently windows doesn't like
// 64k reads on stdin. See #13304 for details, but the idea is that on
// windows we use a slightly smaller buffer that's been seen to be
// acceptable.
let
stdin
=
if
cfg!
(
windows
)
{
BufferedReader
::
with_capacity
(
8
*
1024
,
stdin_raw
())
}
else
{
...
...
@@ -226,15 +235,11 @@ pub fn stdin() -> StdinReader {
// Make sure to free it at exit
rt
::
at_exit
(||
{
let
g
=
LOCK
.lock
();
let
stdin
=
STDIN
;
STDIN
=
1
as
*
const
_
;
drop
(
g
);
mem
::
transmute
::
<
_
,
Box
<
StdinReader
>>
(
stdin
);
mem
::
transmute
::
<
_
,
Box
<
StdinReader
>>
(
STDIN
);
STDIN
=
0
as
*
const
_
;
});
}
else
if
STDIN
as
uint
==
1
{
panic!
(
"accessing stdin after the main thread has exited"
)
}
});
(
*
STDIN
)
.clone
()
}
}
...
...
src/libstd/lib.rs
浏览文件 @
aec67c2e
...
...
@@ -229,13 +229,13 @@
pub
mod
sync
;
pub
mod
comm
;
#[path
=
"sys/common/mod.rs"
]
mod
sys_common
;
#[cfg(unix)]
#[path
=
"sys/unix/mod.rs"
]
mod
sys
;
#[cfg(windows)]
#[path
=
"sys/windows/mod.rs"
]
mod
sys
;
#[path
=
"sys/common/mod.rs"
]
mod
sys_common
;
pub
mod
rt
;
mod
failure
;
...
...
src/libstd/rt/at_exit_imp.rs
浏览文件 @
aec67c2e
...
...
@@ -29,8 +29,6 @@
static
LOCK
:
Mutex
=
MUTEX_INIT
;
static
mut
QUEUE
:
*
mut
Queue
=
0
as
*
mut
Queue
;
const
DTOR_RUN_ITERS
:
uint
=
10
;
unsafe
fn
init
()
{
if
QUEUE
.is_null
()
{
let
state
:
Box
<
Queue
>
=
box
Vec
::
new
();
...
...
@@ -51,7 +49,7 @@ pub fn cleanup() {
unsafe
{
LOCK
.lock
();
let
queue
=
QUEUE
;
QUEUE
=
1
u
as
*
mut
_
;
QUEUE
=
1
as
*
mut
_
;
LOCK
.unlock
();
// make sure we're not recursively cleaning up
...
...
src/libstd/rt/mod.rs
浏览文件 @
aec67c2e
...
...
@@ -92,7 +92,9 @@ fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
// but we just do this to name the main thread and to give it correct
// info about the stack bounds.
let
thread
:
Thread
=
NewThread
::
new
(
Some
(
"<main>"
.to_string
()));
thread_info
::
set
(
sys
::
thread
::
guard
::
main
(),
thread
);
thread_info
::
set
((
my_stack_bottom
,
my_stack_top
),
sys
::
thread
::
guard
::
main
(),
thread
);
// By default, some platforms will send a *signal* when a EPIPE error
// would otherwise be delivered. This runtime doesn't install a SIGPIPE
...
...
@@ -131,14 +133,20 @@ fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
}
}
/// Enqueues a procedure to run when the main thread exits.
/// Enqueues a procedure to run when the runtime is cleaned up
///
/// The procedure passed to this function will be executed as part of the
/// runtime cleanup phase. For normal rust programs, this means that it will run
/// after all other threads have exited.
///
/// The procedure is *not* executed with a local `Thread` available to it, so
/// primitives like logging, I/O, channels, spawning, etc, are *not* available.
/// This is meant for "bare bones" usage to clean up runtime details, this is
/// not meant as a general-purpose "let's clean everything up" function.
///
/// It is forbidden for procedures to register more `at_exit` handlers when they
/// are running, and doing so will lead to a process abort.
///
/// Note that other threads may still be running when `at_exit` routines start
/// running.
pub
fn
at_exit
<
F
:
FnOnce
()
+
Send
>
(
f
:
F
)
{
pub
fn
at_exit
<
F
:
FnOnce
()
+
Send
>
(
f
:
F
)
{
at_exit_imp
::
push
(
Thunk
::
new
(
f
));
}
...
...
@@ -154,5 +162,8 @@ pub fn at_exit<F: FnOnce() + Send>(f: F) {
pub
unsafe
fn
cleanup
()
{
args
::
cleanup
();
sys
::
stack_overflow
::
cleanup
();
at_exit_imp
::
cleanup
();
// FIXME: (#20012): the resources being cleaned up by at_exit
// currently are not prepared for cleanup to happen asynchronously
// with detached threads using the resources; for now, we leak.
// at_exit_imp::cleanup();
}
src/libstd/rt/unwind.rs
浏览文件 @
aec67c2e
...
...
@@ -68,7 +68,7 @@
use
libc
::
c_void
;
use
mem
;
use
sync
::
atomic
;
use
sy
s_common
::
mutex
::{
Mutex
,
MUTEX
_INIT
};
use
sy
nc
::{
Once
,
ONCE
_INIT
};
use
rt
::
libunwind
as
uw
;
...
...
@@ -540,20 +540,11 @@ pub fn begin_unwind<M: Any + Send>(msg: M, file_line: &(&'static str, uint)) ->
/// Doing this split took the LLVM IR line counts of `fn main() { panic!()
/// }` from ~1900/3700 (-O/no opts) to 180/590.
#[inline(never)]
#[cold]
// this is the slow path, please never inline this
fn
begin_unwind_inner
(
msg
:
Box
<
Any
+
Send
>
,
file_line
:
&
(
&
'static
str
,
uint
))
->
!
{
fn
begin_unwind_inner
(
msg
:
Box
<
Any
+
Send
>
,
file_line
:
&
(
&
'static
str
,
uint
))
->
!
{
// Make sure the default failure handler is registered before we look at the
// callbacks.
unsafe
{
static
LOCK
:
Mutex
=
MUTEX_INIT
;
static
mut
INIT
:
bool
=
false
;
LOCK
.lock
();
if
!
INIT
{
register
(
failure
::
on_fail
);
INIT
=
true
;
}
LOCK
.unlock
();
}
static
INIT
:
Once
=
ONCE_INIT
;
INIT
.doit
(||
unsafe
{
register
(
failure
::
on_fail
);
});
// First, invoke call the user-defined callbacks triggered on thread panic.
//
...
...
src/libstd/sys/common/helper_thread.rs
浏览文件 @
aec67c2e
...
...
@@ -20,8 +20,6 @@
//! can be created in the future and there must be no active timers at that
//! time.
#![macro_escape]
use
prelude
::
*
;
use
cell
::
UnsafeCell
;
...
...
@@ -70,17 +68,6 @@ unsafe impl<M:Send> Sync for Helper<M> { }
unsafe
impl
Send
for
RaceBox
{}
unsafe
impl
Sync
for
RaceBox
{}
macro_rules!
helper_init
{
(
static
$name:ident
:
Helper
<
$m:ty
>
)
=>
(
static
$name
:
Helper
<
$m
>
=
Helper
{
lock
:
::
sync
::
MUTEX_INIT
,
cond
:
::
sync
::
CONDVAR_INIT
,
chan
:
::
cell
::
UnsafeCell
{
value
:
0
as
*
mut
Sender
<
$m
>
},
signal
:
::
cell
::
UnsafeCell
{
value
:
0
},
initialized
:
::
cell
::
UnsafeCell
{
value
:
false
},
shutdown
:
::
cell
::
UnsafeCell
{
value
:
false
},
};
)
}
impl
<
M
:
Send
>
Helper
<
M
>
{
/// Lazily boots a helper thread, becoming a no-op if the helper has already
/// been spawned.
...
...
@@ -97,7 +84,7 @@ pub fn boot<T, F>(&'static self, f: F, helper: fn(helper_signal::signal, Receive
{
unsafe
{
let
_
guard
=
self
.lock
.lock
()
.unwrap
();
if
*
self
.chan
.get
()
as
uint
==
0
{
if
!*
self
.initialized
.get
()
{
let
(
tx
,
rx
)
=
channel
();
*
self
.chan
.get
()
=
mem
::
transmute
(
box
tx
);
let
(
receive
,
send
)
=
helper_signal
::
new
();
...
...
@@ -106,17 +93,15 @@ pub fn boot<T, F>(&'static self, f: F, helper: fn(helper_signal::signal, Receive
let
receive
=
RaceBox
(
receive
);
let
t
=
f
();
Thread
::
spawn
(
move
||
{
Thread
::
spawn
(
move
|
:
|
{
helper
(
receive
.0
,
rx
,
t
);
let
_
g
=
self
.lock
.lock
()
.unwrap
();
*
self
.shutdown
.get
()
=
true
;
self
.cond
.notify_one
()
})
.detach
();
rt
::
at_exit
(
move
|
|
{
self
.shutdown
()
});
rt
::
at_exit
(
move
|:
|
{
self
.shutdown
()
});
*
self
.initialized
.get
()
=
true
;
}
else
if
*
self
.chan
.get
()
as
uint
==
1
{
panic!
(
"cannot continue usage after shutdown"
);
}
}
}
...
...
@@ -131,9 +116,7 @@ pub fn send(&'static self, msg: M) {
// Must send and *then* signal to ensure that the child receives the
// message. Otherwise it could wake up and go to sleep before we
// send the message.
assert
!
(
*
self
.chan
.get
()
as
uint
!=
0
);
assert
!
(
*
self
.chan
.get
()
as
uint
!=
1
,
"cannot continue usage after shutdown"
);
assert
!
(
!
self
.chan
.get
()
.is_null
());
(
**
self
.chan
.get
())
.send
(
msg
);
helper_signal
::
signal
(
*
self
.signal
.get
()
as
helper_signal
::
signal
);
}
...
...
@@ -146,13 +129,9 @@ fn shutdown(&'static self) {
// returns.
let
mut
guard
=
self
.lock
.lock
()
.unwrap
();
let
ptr
=
*
self
.chan
.get
();
if
ptr
as
uint
==
1
{
panic!
(
"cannot continue usage after shutdown"
);
}
// Close the channel by destroying it
let
chan
:
Box
<
Sender
<
M
>>
=
mem
::
transmute
(
*
self
.chan
.get
());
*
self
.chan
.get
()
=
1
as
*
mut
Sender
<
M
>
;
*
self
.chan
.get
()
=
0
as
*
mut
Sender
<
M
>
;
drop
(
chan
);
helper_signal
::
signal
(
*
self
.signal
.get
()
as
helper_signal
::
signal
);
...
...
src/libstd/sys/common/mod.rs
浏览文件 @
aec67c2e
...
...
@@ -9,7 +9,7 @@
// except according to those terms.
#![allow(missing_docs)]
#![
macro_escape
]
#![
allow(dead_code)
]
use
io
::{
mod
,
IoError
,
IoResult
};
use
prelude
::
*
;
...
...
src/libstd/sys/common/mutex.rs
浏览文件 @
aec67c2e
...
...
@@ -29,7 +29,6 @@ impl Mutex {
/// Behavior is undefined if the mutex is moved after the first method is
/// called on the mutex.
#[inline]
#[allow(dead_code)]
// sys is not exported yet
pub
unsafe
fn
new
()
->
Mutex
{
Mutex
(
imp
::
Mutex
::
new
())
}
/// Lock the mutex blocking the current thread until it is available.
...
...
src/libstd/sys/common/net.rs
浏览文件 @
aec67c2e
...
...
@@ -23,9 +23,7 @@
use
sys
::{
mod
,
retry
,
c
,
sock_t
,
last_error
,
last_net_error
,
last_gai_error
,
close_sock
,
wrlen
,
msglen_t
,
os
,
wouldblock
,
set_nonblocking
,
timer
,
ms_to_timeval
,
decode_error_detailed
};
use
sync
::
Mutex
;
#[cfg(not(target_os
=
"linux"
))]
use
sync
::
MutexGuard
;
use
sync
::{
Mutex
,
MutexGuard
};
use
sys_common
::{
mod
,
keep_going
,
short_write
,
timeout
};
use
prelude
::
*
;
use
cmp
;
...
...
@@ -613,13 +611,11 @@ impl Drop for Inner {
fn
drop
(
&
mut
self
)
{
unsafe
{
close_sock
(
self
.fd
);
}
}
}
#[cfg(not(target_os
=
"linux"
))]
pub
struct
Guard
<
'a
>
{
pub
fd
:
sock_t
,
pub
guard
:
MutexGuard
<
'a
,
()
>
,
}
#[cfg(not(target_os
=
"linux"
))]
#[unsafe_destructor]
impl
<
'a
>
Drop
for
Guard
<
'a
>
{
fn
drop
(
&
mut
self
)
{
...
...
src/libstd/sys/common/rwlock.rs
浏览文件 @
aec67c2e
...
...
@@ -26,7 +26,6 @@ impl RWLock {
/// Usage of an RWLock is undefined if it is moved after its first use (any
/// function calls below).
#[inline]
#[allow(dead_code)]
// sys is not exported yet
pub
unsafe
fn
new
()
->
RWLock
{
RWLock
(
imp
::
RWLock
::
new
())
}
/// Acquire shared access to the underlying lock, blocking the current
...
...
src/libstd/sys/common/stack.rs
浏览文件 @
aec67c2e
...
...
@@ -121,6 +121,37 @@ pub unsafe fn record_os_managed_stack_bounds(stack_lo: uint, _stack_hi: uint) {
record_sp_limit
(
stack_lo
+
RED_ZONE
);
}
#[inline(always)]
pub
unsafe
fn
record_rust_managed_stack_bounds
(
stack_lo
:
uint
,
stack_hi
:
uint
)
{
// When the old runtime had segmented stacks, it used a calculation that was
// "limit + RED_ZONE + FUDGE". The red zone was for things like dynamic
// symbol resolution, llvm function calls, etc. In theory this red zone
// value is 0, but it matters far less when we have gigantic stacks because
// we don't need to be so exact about our stack budget. The "fudge factor"
// was because LLVM doesn't emit a stack check for functions < 256 bytes in
// size. Again though, we have giant stacks, so we round all these
// calculations up to the nice round number of 20k.
record_sp_limit
(
stack_lo
+
RED_ZONE
);
return
target_record_stack_bounds
(
stack_lo
,
stack_hi
);
#[cfg(not(windows))]
#[inline(always)]
unsafe
fn
target_record_stack_bounds
(
_
stack_lo
:
uint
,
_
stack_hi
:
uint
)
{}
#[cfg(all(windows,
target_arch
=
"x86"
))]
#[inline(always)]
unsafe
fn
target_record_stack_bounds
(
stack_lo
:
uint
,
stack_hi
:
uint
)
{
// stack range is at TIB: %fs:0x04 (top) and %fs:0x08 (bottom)
asm!
(
"mov $0, %fs:0x04"
::
"r"
(
stack_hi
)
::
"volatile"
);
asm!
(
"mov $0, %fs:0x08"
::
"r"
(
stack_lo
)
::
"volatile"
);
}
#[cfg(all(windows,
target_arch
=
"x86_64"
))]
#[inline(always)]
unsafe
fn
target_record_stack_bounds
(
stack_lo
:
uint
,
stack_hi
:
uint
)
{
// stack range is at TIB: %gs:0x08 (top) and %gs:0x10 (bottom)
asm!
(
"mov $0, %gs:0x08"
::
"r"
(
stack_hi
)
::
"volatile"
);
asm!
(
"mov $0, %gs:0x10"
::
"r"
(
stack_lo
)
::
"volatile"
);
}
}
/// Records the current limit of the stack as specified by `end`.
///
/// This is stored in an OS-dependent location, likely inside of the thread
...
...
src/libstd/sys/common/thread_info.rs
浏览文件 @
aec67c2e
...
...
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![allow(dead_code)]
// stack_guard isn't used right now on all platforms
use
core
::
prelude
::
*
;
use
thread
::
Thread
;
...
...
@@ -17,6 +15,10 @@
use
string
::
String
;
struct
ThreadInfo
{
// This field holds the known bounds of the stack in (lo, hi)
// form. Not all threads necessarily know their precise bounds,
// hence this is optional.
stack_bounds
:
(
uint
,
uint
),
stack_guard
:
uint
,
thread
:
Thread
,
}
...
...
@@ -33,6 +35,7 @@ fn with<R>(f: |&mut ThreadInfo| -> R) -> R {
THREAD_INFO
.with
(|
c
|
{
if
c
.borrow
()
.is_none
()
{
*
c
.borrow_mut
()
=
Some
(
ThreadInfo
{
stack_bounds
:
(
0
,
0
),
stack_guard
:
0
,
thread
:
NewThread
::
new
(
None
),
})
...
...
@@ -50,9 +53,10 @@ pub fn stack_guard() -> uint {
ThreadInfo
::
with
(|
info
|
info
.stack_guard
)
}
pub
fn
set
(
stack_guard
:
uint
,
thread
:
Thread
)
{
pub
fn
set
(
stack_
bounds
:
(
uint
,
uint
),
stack_
guard
:
uint
,
thread
:
Thread
)
{
THREAD_INFO
.with
(|
c
|
assert
!
(
c
.borrow
()
.is_none
()));
THREAD_INFO
.with
(
move
|
c
|
*
c
.borrow_mut
()
=
Some
(
ThreadInfo
{
stack_bounds
:
stack_bounds
,
stack_guard
:
stack_guard
,
thread
:
thread
,
}));
...
...
src/libstd/sys/common/thread_local.rs
浏览文件 @
aec67c2e
...
...
@@ -55,11 +55,11 @@
//! ```
#![allow(non_camel_case_types)]
#![allow(dead_code)]
// sys isn't exported yet
use
prelude
::
*
;
use
sync
::
atomic
::{
mod
,
AtomicUint
};
use
sync
::{
Mutex
,
Once
,
ONCE_INIT
};
use
sys
::
thread_local
as
imp
;
...
...
@@ -140,6 +140,9 @@ pub struct Key {
key
:
atomic
::
INIT_ATOMIC_UINT
,
};
static
INIT_KEYS
:
Once
=
ONCE_INIT
;
static
mut
KEYS
:
*
mut
Mutex
<
Vec
<
imp
::
Key
>>
=
0
as
*
mut
_
;
impl
StaticKey
{
/// Gets the value associated with this TLS key
///
...
...
src/libstd/sys/unix/backtrace.rs
浏览文件 @
aec67c2e
...
...
@@ -83,12 +83,12 @@
/// to symbols. This is a bit of a hokey implementation as-is, but it works for
/// all unix platforms we support right now, so it at least gets the job done.
use
prelude
::
*
;
use
c_str
::
CString
;
use
io
::
IoResult
;
use
io
::
{
IoResult
,
Writer
}
;
use
libc
;
use
mem
;
use
option
::
Option
::{
mod
,
Some
,
None
};
use
result
::
Result
::{
Ok
,
Err
};
use
sync
::{
StaticMutex
,
MUTEX_INIT
};
use
sys_common
::
backtrace
::
*
;
...
...
@@ -151,7 +151,7 @@ struct Context<'a> {
// I/O done here is blocking I/O, not green I/O, so we don't have to
// worry about this being a native vs green mutex.
static
LOCK
:
StaticMutex
=
MUTEX_INIT
;
let
_
g
=
LOCK
.lock
()
;
let
_
g
=
unsafe
{
LOCK
.lock
()
}
;
try!
(
writeln!
(
w
,
"stack backtrace:"
));
...
...
@@ -241,8 +241,12 @@ fn dladdr(addr: *const libc::c_void,
#[cfg(not(any(target_os
=
"macos"
,
target_os
=
"ios"
)))]
fn
print
(
w
:
&
mut
Writer
,
idx
:
int
,
addr
:
*
mut
libc
::
c_void
)
->
IoResult
<
()
>
{
use
iter
::{
Iterator
,
IteratorExt
};
use
os
;
use
path
::
GenericPath
;
use
ptr
::
PtrExt
;
use
ptr
;
use
slice
::
SliceExt
;
////////////////////////////////////////////////////////////////////////
// libbacktrace.h API
...
...
src/libstd/sys/unix/mod.rs
浏览文件 @
aec67c2e
...
...
@@ -10,14 +10,30 @@
#![allow(missing_docs)]
#![allow(non_camel_case_types)]
#![allow(unused_imports)]
#![allow(dead_code)]
#![allow(unused_unsafe)]
#![allow(unused_mut)]
extern
crate
libc
;
use
num
;
use
num
::{
Int
,
SignedInt
};
use
prelude
::
*
;
use
io
::{
mod
,
IoResult
,
IoError
};
use
sys_common
::
mkerr_libc
;
macro_rules!
helper_init
{
(
static
$name:ident
:
Helper
<
$m:ty
>
)
=>
(
static
$name
:
Helper
<
$m
>
=
Helper
{
lock
:
::
sync
::
MUTEX_INIT
,
cond
:
::
sync
::
CONDVAR_INIT
,
chan
:
::
cell
::
UnsafeCell
{
value
:
0
as
*
mut
Sender
<
$m
>
},
signal
:
::
cell
::
UnsafeCell
{
value
:
0
},
initialized
:
::
cell
::
UnsafeCell
{
value
:
false
},
shutdown
:
::
cell
::
UnsafeCell
{
value
:
false
},
};
)
}
pub
mod
backtrace
;
pub
mod
c
;
pub
mod
ext
;
...
...
src/libstd/sys/unix/mutex.rs
浏览文件 @
aec67c2e
...
...
@@ -11,6 +11,7 @@
use
cell
::
UnsafeCell
;
use
kinds
::
Sync
;
use
sys
::
sync
as
ffi
;
use
sys_common
::
mutex
;
pub
struct
Mutex
{
inner
:
UnsafeCell
<
ffi
::
pthread_mutex_t
>
}
...
...
@@ -25,7 +26,6 @@ pub unsafe fn raw(m: &Mutex) -> *mut ffi::pthread_mutex_t {
unsafe
impl
Sync
for
Mutex
{}
#[allow(dead_code)]
// sys isn't exported yet
impl
Mutex
{
#[inline]
pub
unsafe
fn
new
()
->
Mutex
{
...
...
src/libstd/sys/unix/os.rs
浏览文件 @
aec67c2e
...
...
@@ -10,16 +10,17 @@
//! Implementation of `std::os` functionality for unix systems
#![allow(unused_imports)]
// lots of cfg code here
use
prelude
::
*
;
use
error
::{
FromError
,
Error
};
use
fmt
;
use
io
::{
IoError
,
IoResult
};
use
libc
::{
mod
,
c_int
,
c_char
};
use
os
;
use
libc
::{
mod
,
c_int
,
c_char
,
c_void
};
use
path
::
BytesContainer
;
use
ptr
;
use
sync
::
atomic
::{
AtomicInt
,
INIT_ATOMIC_INT
,
SeqCst
};
use
sys
::
fs
::
FileDesc
;
use
os
;
use
os
::
TMPBUF_SZ
;
...
...
src/libstd/sys/unix/pipe.rs
浏览文件 @
aec67c2e
...
...
@@ -145,7 +145,7 @@ fn lock_nonblocking(&self) {}
fn
lock_nonblocking
<
'a
>
(
&
'a
self
)
->
Guard
<
'a
>
{
let
ret
=
Guard
{
fd
:
self
.fd
(),
guard
:
self
.inner.lock
.lock
()
.unwrap
()
,
guard
:
unsafe
{
self
.inner.lock
.lock
()
.unwrap
()
}
,
};
assert
!
(
set_nonblocking
(
self
.fd
(),
true
)
.is_ok
());
ret
...
...
src/libstd/sys/unix/process.rs
浏览文件 @
aec67c2e
...
...
@@ -11,7 +11,7 @@
use
libc
::{
mod
,
pid_t
,
c_void
,
c_int
};
use
c_str
::
CString
;
use
io
::{
IoResult
,
EndOfFile
};
use
io
::{
mod
,
IoResult
,
IoError
,
EndOfFile
};
use
mem
;
use
os
;
use
ptr
;
...
...
@@ -327,7 +327,7 @@ pub fn wait(&self, deadline: u64) -> IoResult<ProcessExit> {
// The actual communication between the helper thread and this thread is
// quite simple, just a channel moving data around.
HELPER
.boot
(
register_sigchld
,
waitpid_helper
);
unsafe
{
HELPER
.boot
(
register_sigchld
,
waitpid_helper
)
}
match
self
.try_wait
()
{
Some
(
ret
)
=>
return
Ok
(
ret
),
...
...
@@ -335,7 +335,7 @@ pub fn wait(&self, deadline: u64) -> IoResult<ProcessExit> {
}
let
(
tx
,
rx
)
=
channel
();
HELPER
.send
(
NewChild
(
self
.pid
,
tx
,
deadline
));
unsafe
{
HELPER
.send
(
NewChild
(
self
.pid
,
tx
,
deadline
));
}
return
match
rx
.recv_opt
()
{
Ok
(
e
)
=>
Ok
(
e
),
Err
(())
=>
Err
(
timeout
(
"wait timed out"
)),
...
...
@@ -419,15 +419,8 @@ fn waitpid_helper(input: libc::c_int,
Ok
(
NewChild
(
pid
,
tx
,
deadline
))
=>
{
active
.push
((
pid
,
tx
,
deadline
));
}
// Once we've been disconnected it means the main
// thread is exiting (at_exit has run). We could
// still have active waiter for other threads, so
// we're just going to drop them all on the floor.
// This means that they won't receive a "you're
// done" message in which case they'll be considered
// as timed out, but more generally errors will
// start propagating.
Err
(
comm
::
Disconnected
)
=>
{
assert
!
(
active
.len
()
==
0
);
break
'outer
;
}
Err
(
comm
::
Empty
)
=>
break
,
...
...
src/libstd/sys/unix/rwlock.rs
浏览文件 @
aec67c2e
...
...
@@ -17,7 +17,6 @@ pub struct RWLock { inner: UnsafeCell<ffi::pthread_rwlock_t> }
inner
:
UnsafeCell
{
value
:
ffi
::
PTHREAD_RWLOCK_INITIALIZER
},
};
#[allow(dead_code)]
// sys isn't exported yet
impl
RWLock
{
#[inline]
pub
unsafe
fn
new
()
->
RWLock
{
...
...
src/libstd/sys/unix/stack_overflow.rs
浏览文件 @
aec67c2e
...
...
@@ -34,6 +34,7 @@ fn drop(&mut self) {
#[cfg(any(target_os
=
"linux"
,
target_os
=
"macos"
))]
mod
imp
{
use
core
::
prelude
::
*
;
use
sys_common
::
stack
;
use
super
::
Handler
;
...
...
src/libstd/sys/unix/tcp.rs
浏览文件 @
aec67c2e
...
...
@@ -135,6 +135,10 @@ pub fn accept(&mut self) -> IoResult<TcpStream> {
Err
(
sys_common
::
eof
())
}
pub
fn
socket_name
(
&
mut
self
)
->
IoResult
<
ip
::
SocketAddr
>
{
net
::
sockname
(
self
.fd
(),
libc
::
getsockname
)
}
pub
fn
set_timeout
(
&
mut
self
,
timeout
:
Option
<
u64
>
)
{
self
.deadline
=
timeout
.map
(|
a
|
sys
::
timer
::
now
()
+
a
)
.unwrap_or
(
0
);
}
...
...
src/libstd/sys/unix/timer.rs
浏览文件 @
aec67c2e
...
...
@@ -100,7 +100,7 @@ pub fn now() -> u64 {
fn
helper
(
input
:
libc
::
c_int
,
messages
:
Receiver
<
Req
>
,
_
:
())
{
let
mut
set
:
c
::
fd_set
=
unsafe
{
mem
::
zeroed
()
};
let
fd
=
FileDesc
::
new
(
input
,
true
);
let
mut
fd
=
FileDesc
::
new
(
input
,
true
);
let
mut
timeout
:
libc
::
timeval
=
unsafe
{
mem
::
zeroed
()
};
// active timers are those which are able to be selected upon (and it's a
...
...
@@ -168,15 +168,8 @@ fn signal(active: &mut Vec<Box<Inner>>,
1
=>
{
loop
{
match
messages
.try_recv
()
{
// Once we've been disconnected it means the main thread
// is exiting (at_exit has run). We could still have
// active timers for other threads, so we're just going
// to drop them all on the floor. This is all we can
// really do, however, to prevent resource leakage. The
// remaining timers will likely start panicking quickly
// as they attempt to re-use this thread but are
// disallowed to do so.
Err
(
comm
::
Disconnected
)
=>
{
assert
!
(
active
.len
()
==
0
);
break
'outer
;
}
...
...
src/libstd/sys/unix/tty.rs
浏览文件 @
aec67c2e
...
...
@@ -43,4 +43,5 @@ pub fn set_raw(&mut self, _raw: bool) -> IoResult<()> {
pub
fn
get_winsize
(
&
mut
self
)
->
IoResult
<
(
int
,
int
)
>
{
Err
(
sys_common
::
unimpl
())
}
pub
fn
isatty
(
&
self
)
->
bool
{
false
}
}
src/libstd/sys/windows/backtrace.rs
浏览文件 @
aec67c2e
...
...
@@ -7,22 +7,19 @@
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! As always, windows has something very different than unix, we mainly want
//! to avoid having to depend too much on libunwind for windows.
//!
//! If you google around, you'll find a fair bit of references to built-in
//! functions to get backtraces on windows. It turns out that most of these are
//! in an external library called dbghelp. I was unable to find this library
//! via `-ldbghelp`, but it is apparently normal to do the `dlopen` equivalent
//! of it.
//!
//! You'll also find that there's a function called CaptureStackBackTrace
//! mentioned frequently (which is also easy to use), but sadly I didn't have a
//! copy of that function in my mingw install (maybe it was broken?). Instead,
//! this takes the route of using StackWalk64 in order to walk the stack.
#![allow(dead_code)]
// constants/fields aren't always used on all platforms
/// As always, windows has something very different than unix, we mainly want
/// to avoid having to depend too much on libunwind for windows.
///
/// If you google around, you'll find a fair bit of references to built-in
/// functions to get backtraces on windows. It turns out that most of these are
/// in an external library called dbghelp. I was unable to find this library
/// via `-ldbghelp`, but it is apparently normal to do the `dlopen` equivalent
/// of it.
///
/// You'll also find that there's a function called CaptureStackBackTrace
/// mentioned frequently (which is also easy to use), but sadly I didn't have a
/// copy of that function in my mingw install (maybe it was broken?). Instead,
/// this takes the route of using StackWalk64 in order to walk the stack.
use
c_str
::
CString
;
use
intrinsics
;
...
...
@@ -297,7 +294,7 @@ pub fn write(w: &mut Writer) -> IoResult<()> {
// According to windows documentation, all dbghelp functions are
// single-threaded.
static
LOCK
:
StaticMutex
=
MUTEX_INIT
;
let
_
g
=
LOCK
.lock
()
;
let
_
g
=
unsafe
{
LOCK
.lock
()
}
;
// Open up dbghelp.dll, we don't link to it explicitly because it can't
// always be found. Additionally, it's nice having fewer dependencies.
...
...
src/libstd/sys/windows/c.rs
浏览文件 @
aec67c2e
...
...
@@ -15,6 +15,7 @@
#![allow(non_camel_case_types)]
use
libc
;
use
prelude
::
*
;
pub
const
WSADESCRIPTION_LEN
:
uint
=
256
;
pub
const
WSASYS_STATUS_LEN
:
uint
=
128
;
...
...
src/libstd/sys/windows/fs.rs
浏览文件 @
aec67c2e
...
...
@@ -10,17 +10,21 @@
//! Blocking Windows-based file I/O
use
alloc
::
arc
::
Arc
;
use
libc
::{
mod
,
c_int
};
use
io
;
use
c_str
::
CString
;
use
mem
;
use
ptr
;
use
sys
::
os
::
fill_utf16_buf_and_decode
;
use
path
;
use
ptr
;
use
str
;
use
io
;
use
prelude
::
*
;
use
sys
;
use
sys
::
os
;
use
sys_common
::{
unimpl
,
mkerr_libc
};
use
sys_common
::{
keep_going
,
eof
,
mkerr_libc
};
use
io
::{
FilePermission
,
Write
,
UnstableFileStat
,
Open
,
FileAccess
,
FileMode
};
use
io
::{
IoResult
,
IoError
,
FileStat
,
SeekStyle
};
...
...
@@ -441,7 +445,7 @@ pub fn stat(p: &Path) -> IoResult<FileStat> {
// FIXME: move this to platform-specific modules (for now)?
pub
fn
lstat
(
_
p
:
&
Path
)
->
IoResult
<
FileStat
>
{
// FIXME: implementation is missing
Err
(
unimpl
())
Err
(
super
::
unimpl
())
}
pub
fn
utime
(
p
:
&
Path
,
atime
:
u64
,
mtime
:
u64
)
->
IoResult
<
()
>
{
...
...
src/libstd/sys/windows/mod.rs
浏览文件 @
aec67c2e
...
...
@@ -11,14 +11,30 @@
#![allow(missing_docs)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(unused_imports)]
#![allow(dead_code)]
#![allow(unused_unsafe)]
#![allow(unused_mut)]
extern
crate
libc
;
use
num
;
use
mem
;
use
prelude
::
*
;
use
io
::{
mod
,
IoResult
,
IoError
};
use
sync
::{
Once
,
ONCE_INIT
};
macro_rules!
helper_init
{
(
static
$name:ident
:
Helper
<
$m:ty
>
)
=>
(
static
$name
:
Helper
<
$m
>
=
Helper
{
lock
:
::
sync
::
MUTEX_INIT
,
cond
:
::
sync
::
CONDVAR_INIT
,
chan
:
::
cell
::
UnsafeCell
{
value
:
0
as
*
mut
Sender
<
$m
>
},
signal
:
::
cell
::
UnsafeCell
{
value
:
0
},
initialized
:
::
cell
::
UnsafeCell
{
value
:
false
},
shutdown
:
::
cell
::
UnsafeCell
{
value
:
false
},
};
)
}
pub
mod
backtrace
;
pub
mod
c
;
pub
mod
ext
;
...
...
@@ -164,6 +180,14 @@ pub fn init_net() {
}
}
pub
fn
unimpl
()
->
IoError
{
IoError
{
kind
:
io
::
IoUnavailable
,
desc
:
"operation is not implemented"
,
detail
:
None
,
}
}
pub
fn
to_utf16
(
s
:
Option
<&
str
>
)
->
IoResult
<
Vec
<
u16
>>
{
match
s
{
Some
(
s
)
=>
Ok
({
...
...
src/libstd/sys/windows/os.rs
浏览文件 @
aec67c2e
...
...
@@ -15,6 +15,7 @@
use
prelude
::
*
;
use
fmt
;
use
io
::{
IoResult
,
IoError
};
use
iter
::
repeat
;
use
libc
::{
c_int
,
c_void
};
...
...
src/libstd/sys/windows/pipe.rs
浏览文件 @
aec67c2e
...
...
@@ -365,7 +365,7 @@ pub fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
// acquire the lock.
//
// See comments in close_read() about why this lock is necessary.
let
guard
=
self
.inner.lock
.lock
()
;
let
guard
=
unsafe
{
self
.inner.lock
.lock
()
}
;
if
self
.read_closed
()
{
return
Err
(
eof
())
}
...
...
@@ -441,7 +441,7 @@ pub fn write(&mut self, buf: &[u8]) -> IoResult<()> {
// going after we woke up.
//
// See comments in close_read() about why this lock is necessary.
let
guard
=
self
.inner.lock
.lock
()
;
let
guard
=
unsafe
{
self
.inner.lock
.lock
()
}
;
if
self
.write_closed
()
{
return
Err
(
epipe
())
}
...
...
@@ -516,14 +516,14 @@ pub fn close_read(&mut self) -> IoResult<()> {
// close_read() between steps 1 and 2. By atomically executing steps 1
// and 2 with a lock with respect to close_read(), we're guaranteed that
// no thread will erroneously sit in a read forever.
let
_
guard
=
self
.inner.lock
.lock
()
;
let
_
guard
=
unsafe
{
self
.inner.lock
.lock
()
}
;
self
.inner.read_closed
.store
(
true
,
atomic
::
SeqCst
);
self
.cancel_io
()
}
pub
fn
close_write
(
&
mut
self
)
->
IoResult
<
()
>
{
// see comments in close_read() for why this lock is necessary
let
_
guard
=
self
.inner.lock
.lock
()
;
let
_
guard
=
unsafe
{
self
.inner.lock
.lock
()
}
;
self
.inner.write_closed
.store
(
true
,
atomic
::
SeqCst
);
self
.cancel_io
()
}
...
...
src/libstd/sys/windows/process.rs
浏览文件 @
aec67c2e
...
...
@@ -8,24 +8,25 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
prelude
::
*
;
use
libc
::{
pid_t
,
c_void
};
use
libc
::{
pid_t
,
c_void
,
c_int
};
use
libc
;
use
c_str
::
CString
;
use
io
;
use
mem
;
use
os
;
use
ptr
;
use
io
::
process
::{
ProcessExit
,
ExitStatus
};
use
prelude
::
*
;
use
io
::
process
::{
ProcessExit
,
ExitStatus
,
ExitSignal
};
use
collections
;
use
path
::
BytesContainer
;
use
hash
::
Hash
;
use
io
::{
IoResult
,
IoError
};
use
sys
::
timer
;
use
sys
::
fs
;
use
sys
::{
mod
,
retry
,
c
,
wouldblock
,
set_nonblocking
,
ms_to_timeval
,
timer
};
use
sys
::
fs
::
FileDesc
;
use
sys_common
::{
AsInner
,
timeout
};
use
sys_common
::
helper_thread
::
Helper
;
use
sys_common
::{
AsInner
,
mkerr_libc
,
timeout
};
use
io
::
fs
::
PathExtensions
;
...
...
@@ -120,6 +121,8 @@ pub fn spawn<K, V, C, P>(cfg: &C, in_fd: Option<P>,
use
libc
::
funcs
::
extra
::
msvcrt
::
get_osfhandle
;
use
mem
;
use
iter
::{
Iterator
,
IteratorExt
};
use
str
::
StrExt
;
if
cfg
.gid
()
.is_some
()
||
cfg
.uid
()
.is_some
()
{
return
Err
(
IoError
{
...
...
src/libstd/sys/windows/stack_overflow.rs
浏览文件 @
aec67c2e
...
...
@@ -14,7 +14,7 @@
use
mem
;
use
libc
;
use
libc
::
types
::
os
::
arch
::
extra
::{
LPVOID
,
DWORD
,
LONG
,
BOOL
};
use
sys_common
::
stack
;
use
sys_common
::
{
stack
,
thread_info
}
;
pub
struct
Handler
{
_
data
:
*
mut
libc
::
c_void
...
...
@@ -30,6 +30,14 @@ impl Drop for Handler {
fn
drop
(
&
mut
self
)
{}
}
// get_task_info is called from an exception / signal handler.
// It returns the guard page of the current task or 0 if that
// guard page doesn't exist. None is returned if there's currently
// no local task.
unsafe
fn
get_task_guard_page
()
->
uint
{
thread_info
::
stack_guard
()
}
// This is initialized in init() and only read from after
static
mut
PAGE_SIZE
:
uint
=
0
;
...
...
src/libstd/sys/windows/tcp.rs
浏览文件 @
aec67c2e
...
...
@@ -14,10 +14,11 @@
use
mem
;
use
ptr
;
use
prelude
::
*
;
use
super
::{
last_error
,
last_net_error
,
sock_t
};
use
super
::{
last_error
,
last_net_error
,
retry
,
sock_t
};
use
sync
::{
Arc
,
atomic
};
use
sys
::
fs
::
FileDesc
;
use
sys
::{
mod
,
c
,
set_nonblocking
,
wouldblock
,
timer
};
use
sys_common
::{
timeout
,
eof
,
net
};
use
sys_common
::{
mod
,
timeout
,
eof
,
net
};
pub
use
sys_common
::
net
::
TcpStream
;
...
...
@@ -204,6 +205,10 @@ pub fn accept(&mut self) -> IoResult<TcpStream> {
Err
(
eof
())
}
pub
fn
socket_name
(
&
mut
self
)
->
IoResult
<
ip
::
SocketAddr
>
{
net
::
sockname
(
self
.socket
(),
libc
::
getsockname
)
}
pub
fn
set_timeout
(
&
mut
self
,
timeout
:
Option
<
u64
>
)
{
self
.deadline
=
timeout
.map
(|
a
|
timer
::
now
()
+
a
)
.unwrap_or
(
0
);
}
...
...
src/libstd/sys/windows/thread.rs
浏览文件 @
aec67c2e
...
...
@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
core
::
prelude
::
*
;
use
boxed
::
Box
;
use
cmp
;
use
mem
;
...
...
src/libstd/sys/windows/thread_local.rs
浏览文件 @
aec67c2e
...
...
@@ -137,9 +137,9 @@ unsafe fn init_dtors() {
rt
::
at_exit
(
move
||
{
DTOR_LOCK
.lock
();
let
dtors
=
DTORS
;
DTORS
=
1
as
*
mut
_
;
DTORS
=
0
as
*
mut
_
;
mem
::
transmute
::
<
_
,
Box
<
Vec
<
(
Key
,
Dtor
)
>>>
(
dtors
);
assert
!
(
DTORS
as
uint
==
1
);
// can't re-init after destructing
assert
!
(
DTORS
.is_null
()
);
// can't re-init after destructing
DTOR_LOCK
.unlock
();
});
}
...
...
@@ -147,9 +147,6 @@ unsafe fn init_dtors() {
unsafe
fn
register_dtor
(
key
:
Key
,
dtor
:
Dtor
)
{
DTOR_LOCK
.lock
();
init_dtors
();
assert
!
(
DTORS
as
uint
!=
0
);
assert
!
(
DTORS
as
uint
!=
1
,
"cannot create new TLS keys after the main thread has exited"
);
(
*
DTORS
)
.push
((
key
,
dtor
));
DTOR_LOCK
.unlock
();
}
...
...
@@ -157,9 +154,6 @@ unsafe fn register_dtor(key: Key, dtor: Dtor) {
unsafe
fn
unregister_dtor
(
key
:
Key
)
->
bool
{
DTOR_LOCK
.lock
();
init_dtors
();
assert
!
(
DTORS
as
uint
!=
0
);
assert
!
(
DTORS
as
uint
!=
1
,
"cannot unregister destructors after the main thread has exited"
);
let
ret
=
{
let
dtors
=
&
mut
*
DTORS
;
let
before
=
dtors
.len
();
...
...
@@ -238,7 +232,6 @@ unsafe fn unregister_dtor(key: Key) -> bool {
}
}
#[allow(dead_code)]
// not actually dead
unsafe
fn
run_dtors
()
{
let
mut
any_run
=
true
;
for
_
in
range
(
0
,
5
i
)
{
...
...
src/libstd/sys/windows/timer.rs
浏览文件 @
aec67c2e
...
...
@@ -26,6 +26,8 @@
use
ptr
;
use
comm
;
use
sys
::
c
;
use
sys
::
fs
::
FileDesc
;
use
sys_common
::
helper_thread
::
Helper
;
use
prelude
::
*
;
use
io
::
IoResult
;
...
...
@@ -78,10 +80,9 @@ fn helper(input: libc::HANDLE, messages: Receiver<Req>, _: ()) {
None
=>
{}
}
}
// See the comment in unix::timer for why we don't have any
// asserts here and why we're likely just leaving timers on
// the floor as we exit.
Err
(
comm
::
Disconnected
)
=>
{
assert_eq!
(
objs
.len
(),
1
);
assert_eq!
(
chans
.len
(),
0
);
break
'outer
;
}
Err
(
..
)
=>
break
...
...
src/libstd/sys/windows/tty.rs
浏览文件 @
aec67c2e
...
...
@@ -26,6 +26,7 @@
//! to working in raw UTF-16, with such a wrapper around it.
use
super
::
c
::{
ReadConsoleW
,
WriteConsoleW
,
GetConsoleMode
,
SetConsoleMode
};
use
super
::
c
::{
ERROR_ILLEGAL_CHARACTER
};
use
super
::
c
::{
ENABLE_ECHO_INPUT
,
ENABLE_EXTENDED_FLAGS
};
use
super
::
c
::{
ENABLE_INSERT_MODE
,
ENABLE_LINE_INPUT
};
use
super
::
c
::{
ENABLE_PROCESSED_INPUT
,
ENABLE_QUICK_EDIT_MODE
};
...
...
@@ -38,8 +39,6 @@
use
ptr
;
use
str
::
from_utf8
;
use
sys_common
::
unimpl
;
fn
invalid_encoding
()
->
IoError
{
IoError
{
kind
:
io
::
InvalidInput
,
...
...
@@ -151,8 +150,11 @@ pub fn get_winsize(&mut self) -> IoResult<(int, int)> {
// Make a CONSOLE_SCREEN_BUFFER_INFO
// Call GetConsoleScreenBufferInfo
// Maybe call GetLargestConsoleWindowSize instead?
Err
(
unimpl
())
Err
(
super
::
unimpl
())
}
// Let us magically declare this as a TTY
pub
fn
isatty
(
&
self
)
->
bool
{
true
}
}
impl
Drop
for
TTY
{
...
...
src/libstd/thread.rs
浏览文件 @
aec67c2e
...
...
@@ -232,10 +232,13 @@ fn spawn_inner<T: Send>(self, f: Thunk<(), T>) -> JoinGuard<T> {
let
my_stack_top
=
addr
as
uint
;
let
my_stack_bottom
=
my_stack_top
-
stack_size
+
1024
;
unsafe
{
stack
::
record_os_managed_stack_bounds
(
my_stack_bottom
,
my_stack_top
);
thread_info
::
set
(
imp
::
guard
::
current
(),
their_thread
);
stack
::
record_os_managed_stack_bounds
(
my_stack_bottom
,
my_stack_top
);
}
thread_info
::
set
(
(
my_stack_bottom
,
my_stack_top
),
unsafe
{
imp
::
guard
::
current
()
},
their_thread
);
let
mut
output
=
None
;
let
f
:
Thunk
<
(),
T
>
=
if
stdout
.is_some
()
||
stderr
.is_some
()
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录