Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
71448d7c
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,发现更多精彩内容 >>
提交
71448d7c
编写于
8月 27, 2013
作者:
H
Huon Wilson
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Rename UnsafeAtomicRcBox to UnsafeArc. Fixes #7674.
上级
604ab947
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
72 addition
and
72 deletion
+72
-72
src/libextra/arc.rs
src/libextra/arc.rs
+7
-7
src/libextra/sync.rs
src/libextra/sync.rs
+3
-3
src/libstd/rt/comm.rs
src/libstd/rt/comm.rs
+5
-5
src/libstd/rt/kill.rs
src/libstd/rt/kill.rs
+7
-7
src/libstd/rt/message_queue.rs
src/libstd/rt/message_queue.rs
+3
-3
src/libstd/rt/mod.rs
src/libstd/rt/mod.rs
+2
-2
src/libstd/rt/sleeper_list.rs
src/libstd/rt/sleeper_list.rs
+3
-3
src/libstd/unstable/sync.rs
src/libstd/unstable/sync.rs
+42
-42
未找到文件。
src/libextra/arc.rs
浏览文件 @
71448d7c
...
...
@@ -44,7 +44,7 @@
use
sync
::{
Mutex
,
RWLock
};
use
std
::
cast
;
use
std
::
unstable
::
sync
::
UnsafeA
tomicRcBox
;
use
std
::
unstable
::
sync
::
UnsafeA
rc
;
use
std
::
task
;
use
std
::
borrow
;
...
...
@@ -108,7 +108,7 @@ pub fn broadcast_on(&self, condvar_id: uint) -> uint {
****************************************************************************/
/// An atomically reference counted wrapper for shared immutable state.
pub
struct
Arc
<
T
>
{
priv
x
:
UnsafeA
tomicRcBox
<
T
>
}
pub
struct
Arc
<
T
>
{
priv
x
:
UnsafeA
rc
<
T
>
}
/**
...
...
@@ -118,7 +118,7 @@ pub struct Arc<T> { priv x: UnsafeAtomicRcBox<T> }
impl
<
T
:
Freeze
+
Send
>
Arc
<
T
>
{
/// Create an atomically reference counted wrapper.
pub
fn
new
(
data
:
T
)
->
Arc
<
T
>
{
Arc
{
x
:
UnsafeA
tomicRcBox
::
new
(
data
)
}
Arc
{
x
:
UnsafeA
rc
::
new
(
data
)
}
}
pub
fn
get
<
'a
>
(
&
'a
self
)
->
&
'a
T
{
...
...
@@ -160,7 +160,7 @@ fn clone(&self) -> Arc<T> {
#[doc(hidden)]
struct
MutexArcInner
<
T
>
{
priv
lock
:
Mutex
,
priv
failed
:
bool
,
priv
data
:
T
}
/// An Arc with mutable data protected by a blocking mutex.
struct
MutexArc
<
T
>
{
priv
x
:
UnsafeA
tomicRcBox
<
MutexArcInner
<
T
>>
}
struct
MutexArc
<
T
>
{
priv
x
:
UnsafeA
rc
<
MutexArcInner
<
T
>>
}
impl
<
T
:
Send
>
Clone
for
MutexArc
<
T
>
{
...
...
@@ -187,7 +187,7 @@ pub fn new_with_condvars(user_data: T, num_condvars: uint) -> MutexArc<T> {
lock
:
Mutex
::
new_with_condvars
(
num_condvars
),
failed
:
false
,
data
:
user_data
};
MutexArc
{
x
:
UnsafeA
tomicRcBox
::
new
(
data
)
}
MutexArc
{
x
:
UnsafeA
rc
::
new
(
data
)
}
}
/**
...
...
@@ -309,7 +309,7 @@ struct RWArcInner<T> { priv lock: RWLock, priv failed: bool, priv data: T }
*/
#[no_freeze]
struct
RWArc
<
T
>
{
priv
x
:
UnsafeA
tomicRcBox
<
RWArcInner
<
T
>>
,
priv
x
:
UnsafeA
rc
<
RWArcInner
<
T
>>
,
}
impl
<
T
:
Freeze
+
Send
>
Clone
for
RWArc
<
T
>
{
...
...
@@ -335,7 +335,7 @@ pub fn new_with_condvars(user_data: T, num_condvars: uint) -> RWArc<T> {
lock
:
RWLock
::
new_with_condvars
(
num_condvars
),
failed
:
false
,
data
:
user_data
};
RWArc
{
x
:
UnsafeA
tomicRcBox
::
new
(
data
),
}
RWArc
{
x
:
UnsafeA
rc
::
new
(
data
),
}
}
/**
...
...
src/libextra/sync.rs
浏览文件 @
71448d7c
...
...
@@ -21,7 +21,7 @@
use
std
::
comm
::
SendDeferred
;
use
std
::
comm
::{
GenericPort
,
Peekable
};
use
std
::
task
;
use
std
::
unstable
::
sync
::{
Exclusive
,
UnsafeA
tomicRcBox
};
use
std
::
unstable
::
sync
::{
Exclusive
,
UnsafeA
rc
};
use
std
::
unstable
::
atomics
;
use
std
::
unstable
::
finally
::
Finally
;
use
std
::
util
;
...
...
@@ -448,7 +448,7 @@ struct RWLockInner {
pub
struct
RWLock
{
priv
order_lock
:
Semaphore
,
priv
access_lock
:
Sem
<~
[
WaitQueue
]
>
,
priv
state
:
UnsafeA
tomicRcBox
<
RWLockInner
>
,
priv
state
:
UnsafeA
rc
<
RWLockInner
>
,
}
impl
RWLock
{
...
...
@@ -460,7 +460,7 @@ pub fn new() -> RWLock { RWLock::new_with_condvars(1) }
* Similar to mutex_with_condvars.
*/
pub
fn
new_with_condvars
(
num_condvars
:
uint
)
->
RWLock
{
let
state
=
UnsafeA
tomicRcBox
::
new
(
RWLockInner
{
let
state
=
UnsafeA
rc
::
new
(
RWLockInner
{
read_mode
:
false
,
read_count
:
atomics
::
AtomicUint
::
new
(
0
),
});
...
...
src/libstd/rt/comm.rs
浏览文件 @
71448d7c
...
...
@@ -21,7 +21,7 @@
use
rt
::
select
::{
SelectInner
,
SelectPortInner
};
use
select
::{
Select
,
SelectPort
};
use
unstable
::
atomics
::{
AtomicUint
,
AtomicOption
,
Acquire
,
Relaxed
,
SeqCst
};
use
unstable
::
sync
::
UnsafeA
tomicRcBox
;
use
unstable
::
sync
::
UnsafeA
rc
;
use
util
::
Void
;
use
comm
::{
GenericChan
,
GenericSmartChan
,
GenericPort
,
Peekable
};
use
cell
::
Cell
;
...
...
@@ -567,14 +567,14 @@ impl<'self, T> SelectPort<T> for &'self Port<T> { }
pub
struct
SharedChan
<
T
>
{
// Just like Chan, but a shared AtomicOption instead of Cell
priv
next
:
UnsafeA
tomicRcBox
<
AtomicOption
<
StreamChanOne
<
T
>>>
priv
next
:
UnsafeA
rc
<
AtomicOption
<
StreamChanOne
<
T
>>>
}
impl
<
T
>
SharedChan
<
T
>
{
pub
fn
new
(
chan
:
Chan
<
T
>
)
->
SharedChan
<
T
>
{
let
next
=
chan
.next
.take
();
let
next
=
AtomicOption
::
new
(
~
next
);
SharedChan
{
next
:
UnsafeA
tomicRcBox
::
new
(
next
)
}
SharedChan
{
next
:
UnsafeA
rc
::
new
(
next
)
}
}
}
...
...
@@ -620,7 +620,7 @@ fn clone(&self) -> SharedChan<T> {
pub
struct
SharedPort
<
T
>
{
// The next port on which we will receive the next port on which we will receive T
priv
next_link
:
UnsafeA
tomicRcBox
<
AtomicOption
<
PortOne
<
StreamPortOne
<
T
>>>>
priv
next_link
:
UnsafeA
rc
<
AtomicOption
<
PortOne
<
StreamPortOne
<
T
>>>>
}
impl
<
T
>
SharedPort
<
T
>
{
...
...
@@ -630,7 +630,7 @@ pub fn new(port: Port<T>) -> SharedPort<T> {
let
(
next_link_port
,
next_link_chan
)
=
oneshot
();
next_link_chan
.send
(
next_data_port
);
let
next_link
=
AtomicOption
::
new
(
~
next_link_port
);
SharedPort
{
next_link
:
UnsafeA
tomicRcBox
::
new
(
next_link
)
}
SharedPort
{
next_link
:
UnsafeA
rc
::
new
(
next_link
)
}
}
}
...
...
src/libstd/rt/kill.rs
浏览文件 @
71448d7c
...
...
@@ -159,7 +159,7 @@ fn test_something_in_another_task {
use
task
::
spawn
::
Taskgroup
;
use
to_bytes
::
IterBytes
;
use
unstable
::
atomics
::{
AtomicUint
,
Relaxed
};
use
unstable
::
sync
::{
UnsafeA
tomicRcBox
,
LittleLock
};
use
unstable
::
sync
::{
UnsafeA
rc
,
LittleLock
};
use
util
;
static
KILLED_MSG
:
&
'static
str
=
"killed by linked failure"
;
...
...
@@ -170,7 +170,7 @@ fn test_something_in_another_task {
static
KILL_UNKILLABLE
:
uint
=
2
;
struct
KillFlag
(
AtomicUint
);
type
KillFlagHandle
=
UnsafeA
tomicRcBox
<
KillFlag
>
;
type
KillFlagHandle
=
UnsafeA
rc
<
KillFlag
>
;
/// A handle to a blocked task. Usually this means having the ~Task pointer by
/// ownership, but if the task is killable, a killer can steal it at any time.
...
...
@@ -211,7 +211,7 @@ struct KillHandleInner {
/// State shared between tasks used for task killing during linked failure.
#[deriving(Clone)]
pub
struct
KillHandle
(
UnsafeA
tomicRcBox
<
KillHandleInner
>
);
pub
struct
KillHandle
(
UnsafeA
rc
<
KillHandleInner
>
);
/// Per-task state related to task death, killing, failure, etc.
pub
struct
Death
{
...
...
@@ -317,7 +317,7 @@ pub fn make_selectable(self, num_handles: uint) -> ~[BlockedTask] {
let
handles
=
match
self
{
Unkillable
(
task
)
=>
{
let
flag
=
unsafe
{
KillFlag
(
AtomicUint
::
new
(
cast
::
transmute
(
task
)))
};
UnsafeA
tomicRcBox
::
newN
(
flag
,
num_handles
)
UnsafeA
rc
::
newN
(
flag
,
num_handles
)
}
Killable
(
flag_arc
)
=>
flag_arc
.cloneN
(
num_handles
),
};
...
...
@@ -380,8 +380,8 @@ impl Eq for KillHandle {
impl
KillHandle
{
pub
fn
new
()
->
(
KillHandle
,
KillFlagHandle
)
{
let
(
flag
,
flag_clone
)
=
UnsafeA
tomicRcBox
::
new2
(
KillFlag
(
AtomicUint
::
new
(
KILL_RUNNING
)));
let
handle
=
KillHandle
(
UnsafeA
tomicRcBox
::
new
(
KillHandleInner
{
UnsafeA
rc
::
new2
(
KillFlag
(
AtomicUint
::
new
(
KILL_RUNNING
)));
let
handle
=
KillHandle
(
UnsafeA
rc
::
new
(
KillHandleInner
{
// Linked failure fields
killed
:
flag
,
unkillable
:
AtomicUint
::
new
(
KILL_RUNNING
),
...
...
@@ -460,7 +460,7 @@ pub fn killed(&self) -> bool {
pub
fn
notify_immediate_failure
(
&
mut
self
)
{
// A benign data race may happen here if there are failing sibling
// tasks that were also spawned-watched. The refcount's write barriers
// in UnsafeA
tomicRcBox
ensure that this write will be seen by the
// in UnsafeA
rc
ensure that this write will be seen by the
// unwrapper/destructor, whichever task may unwrap it.
unsafe
{
(
*
self
.get
())
.any_child_failed
=
true
;
}
}
...
...
src/libstd/rt/message_queue.rs
浏览文件 @
71448d7c
...
...
@@ -16,11 +16,11 @@
use
vec
::
OwnedVector
;
use
cell
::
Cell
;
use
option
::
*
;
use
unstable
::
sync
::{
UnsafeA
tomicRcBox
,
LittleLock
};
use
unstable
::
sync
::{
UnsafeA
rc
,
LittleLock
};
use
clone
::
Clone
;
pub
struct
MessageQueue
<
T
>
{
priv
state
:
UnsafeA
tomicRcBox
<
State
<
T
>>
priv
state
:
UnsafeA
rc
<
State
<
T
>>
}
struct
State
<
T
>
{
...
...
@@ -32,7 +32,7 @@ struct State<T> {
impl
<
T
:
Send
>
MessageQueue
<
T
>
{
pub
fn
new
()
->
MessageQueue
<
T
>
{
MessageQueue
{
state
:
UnsafeA
tomicRcBox
::
new
(
State
{
state
:
UnsafeA
rc
::
new
(
State
{
count
:
0
,
queue
:
~
[],
lock
:
LittleLock
::
new
()
...
...
src/libstd/rt/mod.rs
浏览文件 @
71448d7c
...
...
@@ -74,7 +74,7 @@
use
rt
::
work_queue
::
WorkQueue
;
use
rt
::
uv
::
uvio
::
UvEventLoop
;
use
unstable
::
atomics
::{
AtomicInt
,
SeqCst
};
use
unstable
::
sync
::
UnsafeA
tomicRcBox
;
use
unstable
::
sync
::
UnsafeA
rc
;
use
vec
::{
OwnedVector
,
MutableVector
};
/// The global (exchange) heap.
...
...
@@ -311,7 +311,7 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
// Create a shared cell for transmitting the process exit
// code from the main task to this function.
let
exit_code
=
UnsafeA
tomicRcBox
::
new
(
AtomicInt
::
new
(
0
));
let
exit_code
=
UnsafeA
rc
::
new
(
AtomicInt
::
new
(
0
));
let
exit_code_clone
=
exit_code
.clone
();
// When the main task exits, after all the tasks in the main
...
...
src/libstd/rt/sleeper_list.rs
浏览文件 @
71448d7c
...
...
@@ -15,12 +15,12 @@
use
vec
::
OwnedVector
;
use
option
::{
Option
,
Some
,
None
};
use
cell
::
Cell
;
use
unstable
::
sync
::{
UnsafeA
tomicRcBox
,
LittleLock
};
use
unstable
::
sync
::{
UnsafeA
rc
,
LittleLock
};
use
rt
::
sched
::
SchedHandle
;
use
clone
::
Clone
;
pub
struct
SleeperList
{
priv
state
:
UnsafeA
tomicRcBox
<
State
>
priv
state
:
UnsafeA
rc
<
State
>
}
struct
State
{
...
...
@@ -32,7 +32,7 @@ struct State {
impl
SleeperList
{
pub
fn
new
()
->
SleeperList
{
SleeperList
{
state
:
UnsafeA
tomicRcBox
::
new
(
State
{
state
:
UnsafeA
rc
::
new
(
State
{
count
:
0
,
stack
:
~
[],
lock
:
LittleLock
::
new
()
...
...
src/libstd/unstable/sync.rs
浏览文件 @
71448d7c
...
...
@@ -26,11 +26,11 @@
/// An atomically reference counted pointer.
///
/// Enforces no shared-memory safety.
pub
struct
UnsafeA
tomicRcBox
<
T
>
{
pub
struct
UnsafeA
rc
<
T
>
{
data
:
*
mut
libc
::
c_void
,
}
struct
A
tomicRcBox
Data
<
T
>
{
struct
A
rc
Data
<
T
>
{
count
:
AtomicUint
,
// An unwrapper uses this protocol to communicate with the "other" task that
// drops the last refcount on an arc. Unfortunately this can't be a proper
...
...
@@ -42,51 +42,51 @@ struct AtomicRcBoxData<T> {
}
unsafe
fn
new_inner
<
T
:
Send
>
(
data
:
T
,
refcount
:
uint
)
->
*
mut
libc
::
c_void
{
let
data
=
~
A
tomicRcBox
Data
{
count
:
AtomicUint
::
new
(
refcount
),
unwrapper
:
AtomicOption
::
empty
(),
data
:
Some
(
data
)
};
let
data
=
~
A
rc
Data
{
count
:
AtomicUint
::
new
(
refcount
),
unwrapper
:
AtomicOption
::
empty
(),
data
:
Some
(
data
)
};
cast
::
transmute
(
data
)
}
impl
<
T
:
Send
>
UnsafeA
tomicRcBox
<
T
>
{
pub
fn
new
(
data
:
T
)
->
UnsafeA
tomicRcBox
<
T
>
{
unsafe
{
UnsafeA
tomicRcBox
{
data
:
new_inner
(
data
,
1
)
}
}
impl
<
T
:
Send
>
UnsafeA
rc
<
T
>
{
pub
fn
new
(
data
:
T
)
->
UnsafeA
rc
<
T
>
{
unsafe
{
UnsafeA
rc
{
data
:
new_inner
(
data
,
1
)
}
}
}
/// As new(), but returns an extra pre-cloned handle.
pub
fn
new2
(
data
:
T
)
->
(
UnsafeA
tomicRcBox
<
T
>
,
UnsafeAtomicRcBox
<
T
>
)
{
pub
fn
new2
(
data
:
T
)
->
(
UnsafeA
rc
<
T
>
,
UnsafeArc
<
T
>
)
{
unsafe
{
let
ptr
=
new_inner
(
data
,
2
);
(
UnsafeA
tomicRcBox
{
data
:
ptr
},
UnsafeAtomicRcBox
{
data
:
ptr
})
(
UnsafeA
rc
{
data
:
ptr
},
UnsafeArc
{
data
:
ptr
})
}
}
/// As new(), but returns a vector of as many pre-cloned handles as requested.
pub
fn
newN
(
data
:
T
,
num_handles
:
uint
)
->
~
[
UnsafeA
tomicRcBox
<
T
>
]
{
pub
fn
newN
(
data
:
T
,
num_handles
:
uint
)
->
~
[
UnsafeA
rc
<
T
>
]
{
unsafe
{
if
num_handles
==
0
{
~
[]
// need to free data here
}
else
{
let
ptr
=
new_inner
(
data
,
num_handles
);
vec
::
from_fn
(
num_handles
,
|
_
|
UnsafeA
tomicRcBox
{
data
:
ptr
})
vec
::
from_fn
(
num_handles
,
|
_
|
UnsafeA
rc
{
data
:
ptr
})
}
}
}
/// As newN(), but from an already-existing handle. Uses one xadd.
pub
fn
cloneN
(
self
,
num_handles
:
uint
)
->
~
[
UnsafeA
tomicRcBox
<
T
>
]
{
pub
fn
cloneN
(
self
,
num_handles
:
uint
)
->
~
[
UnsafeA
rc
<
T
>
]
{
if
num_handles
==
0
{
~
[]
// The "num_handles - 1" trick (below) fails in the 0 case.
}
else
{
unsafe
{
let
mut
data
:
~
A
tomicRcBox
Data
<
T
>
=
cast
::
transmute
(
self
.data
);
let
mut
data
:
~
A
rc
Data
<
T
>
=
cast
::
transmute
(
self
.data
);
// Minus one because we are recycling the given handle's refcount.
let
old_count
=
data
.count
.fetch_add
(
num_handles
-
1
,
Acquire
);
// let old_count = data.count.fetch_add(num_handles, Acquire);
assert
!
(
old_count
>=
1
);
let
ptr
=
cast
::
transmute
(
data
);
cast
::
forget
(
self
);
// Don't run the destructor on this handle.
vec
::
from_fn
(
num_handles
,
|
_
|
UnsafeA
tomicRcBox
{
data
:
ptr
})
vec
::
from_fn
(
num_handles
,
|
_
|
UnsafeA
rc
{
data
:
ptr
})
}
}
}
...
...
@@ -94,7 +94,7 @@ pub fn cloneN(self, num_handles: uint) -> ~[UnsafeAtomicRcBox<T>] {
#[inline]
pub
fn
get
(
&
self
)
->
*
mut
T
{
unsafe
{
let
mut
data
:
~
A
tomicRcBox
Data
<
T
>
=
cast
::
transmute
(
self
.data
);
let
mut
data
:
~
A
rc
Data
<
T
>
=
cast
::
transmute
(
self
.data
);
assert
!
(
data
.count
.load
(
Relaxed
)
>
0
);
let
r
:
*
mut
T
=
data
.data
.get_mut_ref
();
cast
::
forget
(
data
);
...
...
@@ -105,7 +105,7 @@ pub fn get(&self) -> *mut T {
#[inline]
pub
fn
get_immut
(
&
self
)
->
*
T
{
unsafe
{
let
data
:
~
A
tomicRcBox
Data
<
T
>
=
cast
::
transmute
(
self
.data
);
let
data
:
~
A
rc
Data
<
T
>
=
cast
::
transmute
(
self
.data
);
assert
!
(
data
.count
.load
(
Relaxed
)
>
0
);
let
r
:
*
T
=
data
.data
.get_ref
();
cast
::
forget
(
data
);
...
...
@@ -122,7 +122,7 @@ pub fn unwrap(self) -> T {
do
task
::
unkillable
{
unsafe
{
let
mut
this
=
this
.take
();
let
mut
data
:
~
A
tomicRcBox
Data
<
T
>
=
cast
::
transmute
(
this
.data
);
let
mut
data
:
~
A
rc
Data
<
T
>
=
cast
::
transmute
(
this
.data
);
// Set up the unwrap protocol.
let
(
p1
,
c1
)
=
comm
::
oneshot
();
// ()
let
(
p2
,
c2
)
=
comm
::
oneshot
();
// bool
...
...
@@ -139,7 +139,7 @@ pub fn unwrap(self) -> T {
// We were the last owner. Can unwrap immediately.
// AtomicOption's destructor will free the server endpoint.
// FIXME(#3224): it should be like this
// let ~A
tomicRcBox
Data { data: user_data, _ } = data;
// let ~A
rc
Data { data: user_data, _ } = data;
// user_data
data
.data
.take_unwrap
()
}
else
{
...
...
@@ -154,7 +154,7 @@ pub fn unwrap(self) -> T {
let
(
c2
,
data
)
=
c2_and_data
.take
();
c2
.send
(
true
);
// FIXME(#3224): it should be like this
// let ~A
tomicRcBox
Data { data: user_data, _ } = data;
// let ~A
rc
Data { data: user_data, _ } = data;
// user_data
let
mut
data
=
data
;
data
.data
.take_unwrap
()
...
...
@@ -183,10 +183,10 @@ pub fn unwrap(self) -> T {
/// As unwrap above, but without blocking. Returns 'Left(self)' if this is
/// not the last reference; 'Right(unwrapped_data)' if so.
pub
fn
try_unwrap
(
self
)
->
Either
<
UnsafeA
tomicRcBox
<
T
>
,
T
>
{
pub
fn
try_unwrap
(
self
)
->
Either
<
UnsafeA
rc
<
T
>
,
T
>
{
unsafe
{
let
mut
this
=
self
;
// FIXME(#4330) mutable self
let
mut
data
:
~
A
tomicRcBox
Data
<
T
>
=
cast
::
transmute
(
this
.data
);
let
mut
data
:
~
A
rc
Data
<
T
>
=
cast
::
transmute
(
this
.data
);
// This can of course race with anybody else who has a handle, but in
// such a case, the returned count will always be at least 2. If we
// see 1, no race was possible. All that matters is 1 or not-1.
...
...
@@ -209,27 +209,27 @@ pub fn try_unwrap(self) -> Either<UnsafeAtomicRcBox<T>, T> {
}
}
impl
<
T
:
Send
>
Clone
for
UnsafeA
tomicRcBox
<
T
>
{
fn
clone
(
&
self
)
->
UnsafeA
tomicRcBox
<
T
>
{
impl
<
T
:
Send
>
Clone
for
UnsafeA
rc
<
T
>
{
fn
clone
(
&
self
)
->
UnsafeA
rc
<
T
>
{
unsafe
{
let
mut
data
:
~
A
tomicRcBox
Data
<
T
>
=
cast
::
transmute
(
self
.data
);
let
mut
data
:
~
A
rc
Data
<
T
>
=
cast
::
transmute
(
self
.data
);
// This barrier might be unnecessary, but I'm not sure...
let
old_count
=
data
.count
.fetch_add
(
1
,
Acquire
);
assert
!
(
old_count
>=
1
);
cast
::
forget
(
data
);
return
UnsafeA
tomicRcBox
{
data
:
self
.data
};
return
UnsafeA
rc
{
data
:
self
.data
};
}
}
}
#[unsafe_destructor]
impl
<
T
>
Drop
for
UnsafeA
tomicRcBox
<
T
>
{
impl
<
T
>
Drop
for
UnsafeA
rc
<
T
>
{
fn
drop
(
&
self
)
{
unsafe
{
if
self
.data
.is_null
()
{
return
;
// Happens when destructing an unwrapper's handle.
}
let
mut
data
:
~
A
tomicRcBox
Data
<
T
>
=
cast
::
transmute
(
self
.data
);
let
mut
data
:
~
A
rc
Data
<
T
>
=
cast
::
transmute
(
self
.data
);
// Must be acquire+release, not just release, to make sure this
// doesn't get reordered to after the unwrapper pointer load.
let
old_count
=
data
.count
.fetch_sub
(
1
,
SeqCst
);
...
...
@@ -355,7 +355,7 @@ struct ExData<T> {
* need to block or deschedule while accessing shared state, use extra::sync::RWArc.
*/
pub
struct
Exclusive
<
T
>
{
x
:
UnsafeA
tomicRcBox
<
ExData
<
T
>>
x
:
UnsafeA
rc
<
ExData
<
T
>>
}
impl
<
T
:
Send
>
Clone
for
Exclusive
<
T
>
{
...
...
@@ -373,7 +373,7 @@ pub fn new(user_data: T) -> Exclusive<T> {
data
:
user_data
};
Exclusive
{
x
:
UnsafeA
tomicRcBox
::
new
(
data
)
x
:
UnsafeA
rc
::
new
(
data
)
}
}
...
...
@@ -441,7 +441,7 @@ mod tests {
use
comm
;
use
option
::
*
;
use
prelude
::
*
;
use
super
::{
Exclusive
,
UnsafeA
tomicRcBox
,
atomically
};
use
super
::{
Exclusive
,
UnsafeA
rc
,
atomically
};
use
task
;
use
util
;
...
...
@@ -506,44 +506,44 @@ fn exclusive_new_poison() {
#[test]
fn
arclike_newN
()
{
// Tests that the many-refcounts-at-once constructors don't leak.
let
_
=
UnsafeA
tomicRcBox
::
new2
(
~~
"hello"
);
let
x
=
UnsafeA
tomicRcBox
::
newN
(
~~
"hello"
,
0
);
let
_
=
UnsafeA
rc
::
new2
(
~~
"hello"
);
let
x
=
UnsafeA
rc
::
newN
(
~~
"hello"
,
0
);
assert_eq!
(
x
.len
(),
0
)
let
x
=
UnsafeA
tomicRcBox
::
newN
(
~~
"hello"
,
1
);
let
x
=
UnsafeA
rc
::
newN
(
~~
"hello"
,
1
);
assert_eq!
(
x
.len
(),
1
)
let
x
=
UnsafeA
tomicRcBox
::
newN
(
~~
"hello"
,
10
);
let
x
=
UnsafeA
rc
::
newN
(
~~
"hello"
,
10
);
assert_eq!
(
x
.len
(),
10
)
}
#[test]
fn
arclike_cloneN
()
{
// Tests that the many-refcounts-at-once special-clone doesn't leak.
let
x
=
UnsafeA
tomicRcBox
::
new
(
~~
"hello"
);
let
x
=
UnsafeA
rc
::
new
(
~~
"hello"
);
let
x
=
x
.cloneN
(
0
);
assert_eq!
(
x
.len
(),
0
);
let
x
=
UnsafeA
tomicRcBox
::
new
(
~~
"hello"
);
let
x
=
UnsafeA
rc
::
new
(
~~
"hello"
);
let
x
=
x
.cloneN
(
1
);
assert_eq!
(
x
.len
(),
1
);
let
x
=
UnsafeA
tomicRcBox
::
new
(
~~
"hello"
);
let
x
=
UnsafeA
rc
::
new
(
~~
"hello"
);
let
x
=
x
.cloneN
(
10
);
assert_eq!
(
x
.len
(),
10
);
}
#[test]
fn
arclike_unwrap_basic
()
{
let
x
=
UnsafeA
tomicRcBox
::
new
(
~~
"hello"
);
let
x
=
UnsafeA
rc
::
new
(
~~
"hello"
);
assert
!
(
x
.unwrap
()
==
~~
"hello"
);
}
#[test]
fn
arclike_try_unwrap
()
{
let
x
=
UnsafeA
tomicRcBox
::
new
(
~~
"hello"
);
let
x
=
UnsafeA
rc
::
new
(
~~
"hello"
);
assert
!
(
x
.try_unwrap
()
.expect_right
(
"try_unwrap failed"
)
==
~~
"hello"
);
}
#[test]
fn
arclike_try_unwrap_fail
()
{
let
x
=
UnsafeA
tomicRcBox
::
new
(
~~
"hello"
);
let
x
=
UnsafeA
rc
::
new
(
~~
"hello"
);
let
x2
=
x
.clone
();
let
left_x
=
x
.try_unwrap
();
assert
!
(
left_x
.is_left
());
...
...
@@ -554,7 +554,7 @@ fn arclike_try_unwrap_fail() {
#[test]
fn
arclike_try_unwrap_unwrap_race
()
{
// When an unwrap and a try_unwrap race, the unwrapper should always win.
let
x
=
UnsafeA
tomicRcBox
::
new
(
~~
"hello"
);
let
x
=
UnsafeA
rc
::
new
(
~~
"hello"
);
let
x2
=
Cell
::
new
(
x
.clone
());
let
(
p
,
c
)
=
comm
::
stream
();
do
task
::
spawn
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录