Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
b81da278
R
Rust
项目概览
int
/
Rust
11 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
b81da278
编写于
6月 09, 2018
作者:
N
NODA, Kai
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
libstd: add an RAII utility for sys_common::mutex::Mutex
Signed-off-by:
N
NODA, Kai
<
nodakai@gmail.com
>
上级
0f8f4903
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
73 addition
and
69 deletion
+73
-69
src/libstd/io/lazy.rs
src/libstd/io/lazy.rs
+11
-10
src/libstd/sync/mutex.rs
src/libstd/sync/mutex.rs
+2
-2
src/libstd/sys/redox/args.rs
src/libstd/sys/redox/args.rs
+6
-10
src/libstd/sys/unix/args.rs
src/libstd/sys/unix/args.rs
+5
-9
src/libstd/sys/unix/os.rs
src/libstd/sys/unix/os.rs
+9
-17
src/libstd/sys_common/at_exit_imp.rs
src/libstd/sys_common/at_exit_imp.rs
+14
-13
src/libstd/sys_common/mutex.rs
src/libstd/sys_common/mutex.rs
+24
-2
src/libstd/sys_common/thread_local.rs
src/libstd/sys_common/thread_local.rs
+1
-2
src/libstd/thread/mod.rs
src/libstd/thread/mod.rs
+1
-4
未找到文件。
src/libstd/io/lazy.rs
浏览文件 @
b81da278
...
...
@@ -20,6 +20,9 @@ pub struct Lazy<T> {
init
:
fn
()
->
Arc
<
T
>
,
}
#[inline]
const
fn
done
<
T
>
()
->
*
mut
Arc
<
T
>
{
1_u
size
as
*
mut
_
}
unsafe
impl
<
T
>
Sync
for
Lazy
<
T
>
{}
impl
<
T
:
Send
+
Sync
+
'static
>
Lazy
<
T
>
{
...
...
@@ -33,17 +36,15 @@ pub const fn new(init: fn() -> Arc<T>) -> Lazy<T> {
pub
fn
get
(
&
'static
self
)
->
Option
<
Arc
<
T
>>
{
unsafe
{
self
.lock
.lock
();
let
_
guard
=
self
.lock
.lock
();
let
ptr
=
self
.ptr
.get
();
let
ret
=
if
ptr
.is_null
()
{
if
ptr
.is_null
()
{
Some
(
self
.init
())
}
else
if
ptr
as
usize
==
1
{
}
else
if
ptr
==
done
()
{
None
}
else
{
Some
((
*
ptr
)
.clone
())
};
self
.lock
.unlock
();
return
ret
}
}
}
...
...
@@ -53,10 +54,10 @@ unsafe fn init(&'static self) -> Arc<T> {
// the at exit handler). Otherwise we just return the freshly allocated
// `Arc`.
let
registered
=
sys_common
::
at_exit
(
move
||
{
self
.lock
.lock
();
let
ptr
=
self
.ptr
.get
();
self
.ptr
.set
(
1
as
*
mut
_
);
self
.lock
.unlock
()
;
let
ptr
=
{
let
_
guard
=
self
.lock
.lock
();
self
.ptr
.replace
(
done
())
}
;
drop
(
Box
::
from_raw
(
ptr
))
});
let
ret
=
(
self
.init
)();
...
...
src/libstd/sync/mutex.rs
浏览文件 @
b81da278
...
...
@@ -227,7 +227,7 @@ impl<T: ?Sized> Mutex<T> {
#[stable(feature
=
"rust1"
,
since
=
"1.0.0"
)]
pub
fn
lock
(
&
self
)
->
LockResult
<
MutexGuard
<
T
>>
{
unsafe
{
self
.inner
.lock
();
self
.inner
.
raw_
lock
();
MutexGuard
::
new
(
self
)
}
}
...
...
@@ -454,7 +454,7 @@ impl<'a, T: ?Sized> Drop for MutexGuard<'a, T> {
fn
drop
(
&
mut
self
)
{
unsafe
{
self
.__lock.poison
.done
(
&
self
.__poison
);
self
.__lock.inner
.unlock
();
self
.__lock.inner
.
raw_
unlock
();
}
}
}
...
...
src/libstd/sys/redox/args.rs
浏览文件 @
b81da278
...
...
@@ -73,17 +73,15 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) {
CStr
::
from_ptr
(
*
argv
.offset
(
i
)
as
*
const
libc
::
c_char
)
.to_bytes
()
.to_vec
()
})
.collect
();
LOCK
.lock
();
let
_
guard
=
LOCK
.lock
();
let
ptr
=
get_global_ptr
();
assert
!
((
*
ptr
)
.is_none
());
(
*
ptr
)
=
Some
(
box
args
);
LOCK
.unlock
();
}
pub
unsafe
fn
cleanup
()
{
LOCK
.lock
();
let
_
guard
=
LOCK
.lock
();
*
get_global_ptr
()
=
None
;
LOCK
.unlock
();
}
pub
fn
args
()
->
Args
{
...
...
@@ -96,16 +94,14 @@ pub fn args() -> Args {
fn
clone
()
->
Option
<
Vec
<
Vec
<
u8
>>>
{
unsafe
{
LOCK
.lock
();
let
_
guard
=
LOCK
.lock
();
let
ptr
=
get_global_ptr
();
let
ret
=
(
*
ptr
)
.as_ref
()
.map
(|
s
|
(
**
s
)
.clone
());
LOCK
.unlock
();
return
ret
(
*
ptr
)
.as_ref
()
.map
(|
s
|
(
**
s
)
.clone
())
}
}
fn
get_global_ptr
()
->
*
mut
Option
<
Box
<
Vec
<
Vec
<
u8
>>>>
{
unsafe
{
mem
::
transmute
(
&
GLOBAL_ARGS_PTR
)
}
unsafe
fn
get_global_ptr
()
->
*
mut
Option
<
Box
<
Vec
<
Vec
<
u8
>>>>
{
mem
::
transmute
(
&
GLOBAL_ARGS_PTR
)
}
}
src/libstd/sys/unix/args.rs
浏览文件 @
b81da278
...
...
@@ -82,17 +82,15 @@ mod imp {
static
LOCK
:
Mutex
=
Mutex
::
new
();
pub
unsafe
fn
init
(
argc
:
isize
,
argv
:
*
const
*
const
u8
)
{
LOCK
.lock
();
let
_
guard
=
LOCK
.lock
();
ARGC
=
argc
;
ARGV
=
argv
;
LOCK
.unlock
();
}
pub
unsafe
fn
cleanup
()
{
LOCK
.lock
();
let
_
guard
=
LOCK
.lock
();
ARGC
=
0
;
ARGV
=
ptr
::
null
();
LOCK
.unlock
();
}
pub
fn
args
()
->
Args
{
...
...
@@ -104,13 +102,11 @@ pub fn args() -> Args {
fn
clone
()
->
Vec
<
OsString
>
{
unsafe
{
LOCK
.lock
();
let
ret
=
(
0
..
ARGC
)
.map
(|
i
|
{
let
_
guard
=
LOCK
.lock
();
(
0
..
ARGC
)
.map
(|
i
|
{
let
cstr
=
CStr
::
from_ptr
(
*
ARGV
.offset
(
i
)
as
*
const
libc
::
c_char
);
OsStringExt
::
from_vec
(
cstr
.to_bytes
()
.to_vec
())
})
.collect
();
LOCK
.unlock
();
return
ret
})
.collect
()
}
}
}
...
...
src/libstd/sys/unix/os.rs
浏览文件 @
b81da278
...
...
@@ -409,10 +409,9 @@ pub unsafe fn environ() -> *mut *const *const c_char {
/// environment variables of the current process.
pub
fn
env
()
->
Env
{
unsafe
{
ENV_LOCK
.lock
();
let
_
guard
=
ENV_LOCK
.lock
();
let
mut
environ
=
*
environ
();
if
environ
==
ptr
::
null
()
{
ENV_LOCK
.unlock
();
panic!
(
"os::env() failure getting env string from OS: {}"
,
io
::
Error
::
last_os_error
());
}
...
...
@@ -423,12 +422,10 @@ pub fn env() -> Env {
}
environ
=
environ
.offset
(
1
);
}
let
ret
=
Env
{
return
Env
{
iter
:
result
.into_iter
(),
_
dont_send_or_sync_me
:
PhantomData
,
};
ENV_LOCK
.unlock
();
return
ret
}
}
fn
parse
(
input
:
&
[
u8
])
->
Option
<
(
OsString
,
OsString
)
>
{
...
...
@@ -452,15 +449,14 @@ pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
// always None as well
let
k
=
CString
::
new
(
k
.as_bytes
())
?
;
unsafe
{
ENV_LOCK
.lock
();
let
_
guard
=
ENV_LOCK
.lock
();
let
s
=
libc
::
getenv
(
k
.as_ptr
())
as
*
const
libc
::
c_char
;
let
ret
=
if
s
.is_null
()
{
None
}
else
{
Some
(
OsStringExt
::
from_vec
(
CStr
::
from_ptr
(
s
)
.to_bytes
()
.to_vec
()))
};
ENV_LOCK
.unlock
();
return
Ok
(
ret
)
Ok
(
ret
)
}
}
...
...
@@ -469,10 +465,8 @@ pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
let
v
=
CString
::
new
(
v
.as_bytes
())
?
;
unsafe
{
ENV_LOCK
.lock
();
let
ret
=
cvt
(
libc
::
setenv
(
k
.as_ptr
(),
v
.as_ptr
(),
1
))
.map
(|
_
|
());
ENV_LOCK
.unlock
();
return
ret
let
_
guard
=
ENV_LOCK
.lock
();
cvt
(
libc
::
setenv
(
k
.as_ptr
(),
v
.as_ptr
(),
1
))
.map
(|
_
|
())
}
}
...
...
@@ -480,10 +474,8 @@ pub fn unsetenv(n: &OsStr) -> io::Result<()> {
let
nbuf
=
CString
::
new
(
n
.as_bytes
())
?
;
unsafe
{
ENV_LOCK
.lock
();
let
ret
=
cvt
(
libc
::
unsetenv
(
nbuf
.as_ptr
()))
.map
(|
_
|
());
ENV_LOCK
.unlock
();
return
ret
let
_
guard
=
ENV_LOCK
.lock
();
cvt
(
libc
::
unsetenv
(
nbuf
.as_ptr
()))
.map
(|
_
|
())
}
}
...
...
src/libstd/sys_common/at_exit_imp.rs
浏览文件 @
b81da278
...
...
@@ -14,6 +14,7 @@
use
boxed
::
FnBox
;
use
ptr
;
use
mem
;
use
sys_common
::
mutex
::
Mutex
;
type
Queue
=
Vec
<
Box
<
FnBox
()
>>
;
...
...
@@ -25,6 +26,8 @@
static
LOCK
:
Mutex
=
Mutex
::
new
();
static
mut
QUEUE
:
*
mut
Queue
=
ptr
::
null_mut
();
const
DONE
:
*
mut
Queue
=
1_u
size
as
*
mut
_
;
// The maximum number of times the cleanup routines will be run. While running
// the at_exit closures new ones may be registered, and this count is the number
// of times the new closures will be allowed to register successfully. After
...
...
@@ -35,7 +38,7 @@ unsafe fn init() -> bool {
if
QUEUE
.is_null
()
{
let
state
:
Box
<
Queue
>
=
box
Vec
::
new
();
QUEUE
=
Box
::
into_raw
(
state
);
}
else
if
QUEUE
as
usize
==
1
{
}
else
if
QUEUE
==
DONE
{
// can't re-init after a cleanup
return
false
}
...
...
@@ -44,18 +47,18 @@ unsafe fn init() -> bool {
}
pub
fn
cleanup
()
{
for
i
in
0
..
ITERS
{
for
i
in
1
..=
ITERS
{
unsafe
{
LOCK
.lock
();
let
queue
=
QUEUE
;
QUEUE
=
if
i
==
ITERS
-
1
{
1
}
else
{
0
}
as
*
mut
_
;
LOCK
.unlock
()
;
let
queue
=
{
let
_
guard
=
LOCK
.lock
()
;
mem
::
replace
(
&
mut
QUEUE
,
if
i
==
ITERS
{
DONE
}
else
{
ptr
::
null_mut
()
})
}
;
// make sure we're not recursively cleaning up
assert
!
(
queue
as
usize
!=
1
);
assert
!
(
queue
!=
DONE
);
// If we never called init, not need to cleanup!
if
queue
as
usize
!=
0
{
if
!
queue
.is_null
()
{
let
queue
:
Box
<
Queue
>
=
Box
::
from_raw
(
queue
);
for
to_run
in
*
queue
{
to_run
();
...
...
@@ -66,15 +69,13 @@ pub fn cleanup() {
}
pub
fn
push
(
f
:
Box
<
FnBox
()
>
)
->
bool
{
let
mut
ret
=
true
;
unsafe
{
LOCK
.lock
();
let
_
guard
=
LOCK
.lock
();
if
init
()
{
(
*
QUEUE
)
.push
(
f
);
true
}
else
{
ret
=
false
;
false
}
LOCK
.unlock
();
}
ret
}
src/libstd/sys_common/mutex.rs
浏览文件 @
b81da278
...
...
@@ -37,7 +37,15 @@ pub unsafe fn init(&mut self) { self.0.init() }
/// Behavior is undefined if the mutex has been moved between this and any
/// previous function call.
#[inline]
pub
unsafe
fn
lock
(
&
self
)
{
self
.0
.lock
()
}
pub
unsafe
fn
raw_lock
(
&
self
)
{
self
.0
.lock
()
}
/// Calls raw_lock() and then returns an RAII guard to guarantee the mutex
/// will be unlocked.
#[inline]
pub
unsafe
fn
lock
(
&
self
)
->
MutexGuard
{
self
.raw_lock
();
MutexGuard
(
&
self
.0
)
}
/// Attempts to lock the mutex without blocking, returning whether it was
/// successfully acquired or not.
...
...
@@ -51,8 +59,11 @@ pub unsafe fn try_lock(&self) -> bool { self.0.try_lock() }
///
/// Behavior is undefined if the current thread does not actually hold the
/// mutex.
///
/// Consider switching from the pair of raw_lock() and raw_unlock() to
/// lock() whenever possible.
#[inline]
pub
unsafe
fn
unlock
(
&
self
)
{
self
.0
.unlock
()
}
pub
unsafe
fn
raw_
unlock
(
&
self
)
{
self
.0
.unlock
()
}
/// Deallocates all resources associated with this mutex.
///
...
...
@@ -64,3 +75,14 @@ pub unsafe fn destroy(&self) { self.0.destroy() }
// not meant to be exported to the outside world, just the containing module
pub
fn
raw
(
mutex
:
&
Mutex
)
->
&
imp
::
Mutex
{
&
mutex
.0
}
#[must_use]
/// A simple RAII utility for the above Mutex without the poisoning semantics.
pub
struct
MutexGuard
<
'a
>
(
&
'a
imp
::
Mutex
);
impl
<
'a
>
Drop
for
MutexGuard
<
'a
>
{
#[inline]
fn
drop
(
&
mut
self
)
{
unsafe
{
self
.0
.unlock
();
}
}
}
src/libstd/sys_common/thread_local.rs
浏览文件 @
b81da278
...
...
@@ -162,13 +162,12 @@ unsafe fn lazy_init(&self) -> usize {
// we just simplify the whole branch.
if
imp
::
requires_synchronized_create
()
{
static
INIT_LOCK
:
Mutex
=
Mutex
::
new
();
INIT_LOCK
.lock
();
let
_
guard
=
INIT_LOCK
.lock
();
let
mut
key
=
self
.key
.load
(
Ordering
::
SeqCst
);
if
key
==
0
{
key
=
imp
::
create
(
self
.dtor
)
as
usize
;
self
.key
.store
(
key
,
Ordering
::
SeqCst
);
}
INIT_LOCK
.unlock
();
rtassert!
(
key
!=
0
);
return
key
}
...
...
src/libstd/thread/mod.rs
浏览文件 @
b81da278
...
...
@@ -935,20 +935,17 @@ fn new() -> ThreadId {
static
mut
COUNTER
:
u64
=
0
;
unsafe
{
GUARD
.lock
();
let
_
guard
=
GUARD
.lock
();
// If we somehow use up all our bits, panic so that we're not
// covering up subtle bugs of IDs being reused.
if
COUNTER
==
::
u64
::
MAX
{
GUARD
.unlock
();
panic!
(
"failed to generate unique thread ID: bitspace exhausted"
);
}
let
id
=
COUNTER
;
COUNTER
+=
1
;
GUARD
.unlock
();
ThreadId
(
id
)
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录