Skip to content

Commit 26e466c

Browse files
committed
---
yaml --- r: 95354 b: refs/heads/dist-snap c: f3b1f79 h: refs/heads/master v: v3
1 parent 934a6c6 commit 26e466c

34 files changed

+667
-1015
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ refs/heads/try: c274a6888410ce3e357e014568b43310ed787d36
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c
9-
refs/heads/dist-snap: c147ec6d06b19b6e84f488212d7775b5eb937754
9+
refs/heads/dist-snap: f3b1f79716394a91afa179ee27620679c4651228
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503
1212
refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0

branches/dist-snap/src/libextra/extra.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ pub use std::os;
4646

4747
pub mod c_vec;
4848
pub mod io_util;
49+
pub mod rc;
4950

5051
// Concurrency
5152

branches/dist-snap/src/libstd/rc.rs renamed to branches/dist-snap/src/libextra/rc.rs

Lines changed: 81 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,31 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
/** Task-local reference counted boxes
11+
#[allow(missing_doc)];
1212

13-
The `Rc` type provides shared ownership of an immutable value. Destruction is deterministic, and
14-
will occur as soon as the last owner is gone. It is marked as non-sendable because it avoids the
15-
overhead of atomic reference counting.
13+
/** Task-local reference counted smart pointers
1614
17-
The `RcMut` type provides shared ownership of a mutable value. Since multiple owners prevent
18-
inherited mutability, a dynamic freezing check is used to maintain the invariant that an `&mut`
19-
reference is a unique handle and the type is marked as non-`Freeze`.
15+
Task-local reference counted smart pointers are an alternative to managed boxes with deterministic
16+
destruction. They are restricted to containing types that are either `Send` or `Freeze` (or both) to
17+
prevent cycles.
18+
19+
Neither `Rc<T>` or `RcMut<T>` is ever `Send` and `RcMut<T>` is never `Freeze`. If `T` is `Freeze`, a
20+
cycle cannot be created with `Rc<T>` because there is no way to modify it after creation.
2021
2122
*/
2223

23-
use ptr::RawPtr;
24-
use unstable::intrinsics::transmute;
25-
use ops::Drop;
26-
use kinds::{Freeze, Send};
27-
use clone::{Clone, DeepClone};
24+
25+
use std::cast;
26+
use std::ptr;
27+
use std::unstable::intrinsics;
28+
29+
// Convert ~T into *mut T without dropping it
30+
#[inline]
31+
unsafe fn owned_to_raw<T>(mut box: ~T) -> *mut T {
32+
let ptr = ptr::to_mut_unsafe_ptr(box);
33+
intrinsics::forget(box);
34+
ptr
35+
}
2836

2937
struct RcBox<T> {
3038
value: T,
@@ -35,38 +43,50 @@ struct RcBox<T> {
3543
#[unsafe_no_drop_flag]
3644
#[no_send]
3745
pub struct Rc<T> {
38-
priv ptr: *mut RcBox<T>
46+
priv ptr: *mut RcBox<T>,
47+
}
48+
49+
impl<T> Rc<T> {
50+
unsafe fn new(value: T) -> Rc<T> {
51+
Rc{ptr: owned_to_raw(~RcBox{value: value, count: 1})}
52+
}
53+
}
54+
55+
impl<T: Send> Rc<T> {
56+
pub fn from_send(value: T) -> Rc<T> {
57+
unsafe { Rc::new(value) }
58+
}
3959
}
4060

4161
impl<T: Freeze> Rc<T> {
42-
/// Construct a new reference-counted box from a `Freeze` value
43-
#[inline]
44-
pub fn new(value: T) -> Rc<T> {
45-
unsafe {
46-
Rc::new_unchecked(value)
47-
}
62+
pub fn from_freeze(value: T) -> Rc<T> {
63+
unsafe { Rc::new(value) }
4864
}
4965
}
5066

5167
impl<T> Rc<T> {
52-
/// Unsafety construct a new reference-counted box from any value.
53-
///
54-
/// If the type is not `Freeze`, the `Rc` box will incorrectly still be considered as a `Freeze`
55-
/// type. It is also possible to create cycles, which will leak, and may interact poorly with
56-
/// managed pointers.
5768
#[inline]
58-
pub unsafe fn new_unchecked(value: T) -> Rc<T> {
59-
Rc{ptr: transmute(~RcBox{value: value, count: 1})}
69+
pub fn borrow<'r>(&'r self) -> &'r T {
70+
unsafe { cast::copy_lifetime(self, &(*self.ptr).value) }
6071
}
72+
}
6173

62-
/// Borrow the value contained in the reference-counted box
63-
#[inline]
64-
pub fn borrow<'r>(&'r self) -> &'r T {
65-
unsafe { &(*self.ptr).value }
74+
#[unsafe_destructor]
75+
impl<T> Drop for Rc<T> {
76+
fn drop(&mut self) {
77+
unsafe {
78+
if self.ptr.is_not_null() {
79+
(*self.ptr).count -= 1;
80+
if (*self.ptr).count == 0 {
81+
let _: ~T = cast::transmute(self.ptr);
82+
}
83+
}
84+
}
6685
}
6786
}
6887

6988
impl<T> Clone for Rc<T> {
89+
/// Return a shallow copy of the reference counted pointer.
7090
#[inline]
7191
fn clone(&self) -> Rc<T> {
7292
unsafe {
@@ -77,75 +97,56 @@ impl<T> Clone for Rc<T> {
7797
}
7898

7999
impl<T: DeepClone> DeepClone for Rc<T> {
100+
/// Return a deep copy of the reference counted pointer.
80101
#[inline]
81102
fn deep_clone(&self) -> Rc<T> {
82-
unsafe { Rc::new_unchecked(self.borrow().deep_clone()) }
83-
}
84-
}
85-
86-
#[unsafe_destructor]
87-
impl<T> Drop for Rc<T> {
88-
fn drop(&mut self) {
89-
unsafe {
90-
if self.ptr.is_not_null() {
91-
(*self.ptr).count -= 1;
92-
if (*self.ptr).count == 0 {
93-
let _: ~RcBox<T> = transmute(self.ptr);
94-
}
95-
}
96-
}
103+
unsafe { Rc::new(self.borrow().deep_clone()) }
97104
}
98105
}
99106

100107
#[cfg(test)]
101108
mod test_rc {
102109
use super::*;
103-
use cell::Cell;
110+
use std::cell::Cell;
104111

105112
#[test]
106113
fn test_clone() {
107-
unsafe {
108-
let x = Rc::new_unchecked(Cell::new(5));
109-
let y = x.clone();
110-
do x.borrow().with_mut_ref |inner| {
111-
*inner = 20;
112-
}
113-
assert_eq!(y.borrow().take(), 20);
114+
let x = Rc::from_send(Cell::new(5));
115+
let y = x.clone();
116+
do x.borrow().with_mut_ref |inner| {
117+
*inner = 20;
114118
}
119+
assert_eq!(y.borrow().take(), 20);
115120
}
116121

117122
#[test]
118123
fn test_deep_clone() {
119-
unsafe {
120-
let x = Rc::new_unchecked(Cell::new(5));
121-
let y = x.deep_clone();
122-
do x.borrow().with_mut_ref |inner| {
123-
*inner = 20;
124-
}
125-
assert_eq!(y.borrow().take(), 5);
124+
let x = Rc::from_send(Cell::new(5));
125+
let y = x.deep_clone();
126+
do x.borrow().with_mut_ref |inner| {
127+
*inner = 20;
126128
}
129+
assert_eq!(y.borrow().take(), 5);
127130
}
128131

129132
#[test]
130133
fn test_simple() {
131-
let x = Rc::new(5);
134+
let x = Rc::from_freeze(5);
132135
assert_eq!(*x.borrow(), 5);
133136
}
134137

135138
#[test]
136139
fn test_simple_clone() {
137-
let x = Rc::new(5);
140+
let x = Rc::from_freeze(5);
138141
let y = x.clone();
139142
assert_eq!(*x.borrow(), 5);
140143
assert_eq!(*y.borrow(), 5);
141144
}
142145

143146
#[test]
144147
fn test_destructor() {
145-
unsafe {
146-
let x = Rc::new_unchecked(~5);
147-
assert_eq!(**x.borrow(), 5);
148-
}
148+
let x = Rc::from_send(~5);
149+
assert_eq!(**x.borrow(), 5);
149150
}
150151
}
151152

@@ -170,30 +171,21 @@ pub struct RcMut<T> {
170171
priv ptr: *mut RcMutBox<T>,
171172
}
172173

173-
impl<T: Freeze> RcMut<T> {
174-
/// Construct a new mutable reference-counted box from a `Freeze` value
175-
#[inline]
176-
pub fn new(value: T) -> RcMut<T> {
177-
unsafe { RcMut::new_unchecked(value) }
174+
impl<T> RcMut<T> {
175+
unsafe fn new(value: T) -> RcMut<T> {
176+
RcMut{ptr: owned_to_raw(~RcMutBox{value: value, count: 1, borrow: Nothing})}
178177
}
179178
}
180179

181180
impl<T: Send> RcMut<T> {
182-
/// Construct a new mutable reference-counted box from a `Send` value
183-
#[inline]
184181
pub fn from_send(value: T) -> RcMut<T> {
185-
unsafe { RcMut::new_unchecked(value) }
182+
unsafe { RcMut::new(value) }
186183
}
187184
}
188185

189-
impl<T> RcMut<T> {
190-
/// Unsafety construct a new mutable reference-counted box from any value.
191-
///
192-
/// It is possible to create cycles, which will leak, and may interact
193-
/// poorly with managed pointers.
194-
#[inline]
195-
pub unsafe fn new_unchecked(value: T) -> RcMut<T> {
196-
RcMut{ptr: transmute(~RcMutBox{value: value, count: 1, borrow: Nothing})}
186+
impl<T: Freeze> RcMut<T> {
187+
pub fn from_freeze(value: T) -> RcMut<T> {
188+
unsafe { RcMut::new(value) }
197189
}
198190
}
199191

@@ -231,7 +223,7 @@ impl<T> Drop for RcMut<T> {
231223
if self.ptr.is_not_null() {
232224
(*self.ptr).count -= 1;
233225
if (*self.ptr).count == 0 {
234-
let _: ~RcMutBox<T> = transmute(self.ptr);
226+
let _: ~T = cast::transmute(self.ptr);
235227
}
236228
}
237229
}
@@ -255,7 +247,7 @@ impl<T: DeepClone> DeepClone for RcMut<T> {
255247
fn deep_clone(&self) -> RcMut<T> {
256248
do self.with_borrow |x| {
257249
// FIXME: #6497: should avoid freeze (slow)
258-
unsafe { RcMut::new_unchecked(x.deep_clone()) }
250+
unsafe { RcMut::new(x.deep_clone()) }
259251
}
260252
}
261253
}
@@ -278,7 +270,7 @@ mod test_rc_mut {
278270

279271
#[test]
280272
fn test_deep_clone() {
281-
let x = RcMut::new(5);
273+
let x = RcMut::from_freeze(5);
282274
let y = x.deep_clone();
283275
do x.with_mut_borrow |value| {
284276
*value = 20;
@@ -306,7 +298,7 @@ mod test_rc_mut {
306298

307299
#[test]
308300
fn modify() {
309-
let x = RcMut::new(5);
301+
let x = RcMut::from_freeze(5);
310302
let y = x.clone();
311303

312304
do y.with_mut_borrow |a| {
@@ -328,7 +320,7 @@ mod test_rc_mut {
328320

329321
#[test]
330322
fn release_mutable() {
331-
let x = RcMut::new(5);
323+
let x = RcMut::from_freeze(5);
332324
do x.with_mut_borrow |_| {}
333325
do x.with_borrow |_| {}
334326
}
@@ -348,7 +340,7 @@ mod test_rc_mut {
348340
#[test]
349341
#[should_fail]
350342
fn mutable_dupe() {
351-
let x = RcMut::new(5);
343+
let x = RcMut::from_freeze(5);
352344
let y = x.clone();
353345

354346
do x.with_mut_borrow |_| {
@@ -372,7 +364,7 @@ mod test_rc_mut {
372364
#[test]
373365
#[should_fail]
374366
fn restore_freeze() {
375-
let x = RcMut::new(5);
367+
let x = RcMut::from_freeze(5);
376368
let y = x.clone();
377369

378370
do x.with_borrow |_| {

branches/dist-snap/src/libextra/tempfile.rs

Lines changed: 9 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -15,63 +15,17 @@ use std::os;
1515
use std::rand::Rng;
1616
use std::rand;
1717

18-
/// A wrapper for a path to temporary directory implementing automatic
19-
/// scope-pased deletion.
20-
pub struct TempDir {
21-
priv path: Option<Path>
22-
}
23-
24-
impl TempDir {
25-
/// Attempts to make a temporary directory inside of `tmpdir` whose name
26-
/// will have the suffix `suffix`. The directory will be automatically
27-
/// deleted once the returned wrapper is destroyed.
28-
///
29-
/// If no directory can be created, None is returned.
30-
pub fn new_in(tmpdir: &Path, suffix: &str) -> Option<TempDir> {
31-
if !tmpdir.is_absolute() {
32-
let abs_tmpdir = os::make_absolute(tmpdir);
33-
return TempDir::new_in(&abs_tmpdir, suffix);
34-
}
35-
36-
let mut r = rand::rng();
37-
for _ in range(0u, 1000) {
38-
let p = tmpdir.push(r.gen_ascii_str(16) + suffix);
39-
if os::make_dir(&p, 0x1c0) { // 700
40-
return Some(TempDir { path: Some(p) });
41-
}
42-
}
43-
None
44-
}
45-
46-
/// Attempts to make a temporary directory inside of `os::tmpdir()` whose
47-
/// name will have the suffix `suffix`. The directory will be automatically
48-
/// deleted once the returned wrapper is destroyed.
49-
///
50-
/// If no directory can be created, None is returned.
51-
pub fn new(suffix: &str) -> Option<TempDir> {
52-
TempDir::new_in(&os::tmpdir(), suffix)
53-
}
54-
55-
/// Unwrap the wrapped `std::path::Path` from the `TempDir` wrapper.
56-
/// This discards the wrapper so that the automatic deletion of the
57-
/// temporary directory is prevented.
58-
pub fn unwrap(self) -> Path {
59-
let mut tmpdir = self;
60-
tmpdir.path.take_unwrap()
61-
}
62-
63-
/// Access the wrapped `std::path::Path` to the temporary directory.
64-
pub fn path<'a>(&'a self) -> &'a Path {
65-
self.path.get_ref()
66-
}
67-
}
68-
69-
impl Drop for TempDir {
70-
fn drop(&mut self) {
71-
for path in self.path.iter() {
72-
os::remove_dir_recursive(path);
18+
/// Attempts to make a temporary directory inside of `tmpdir` whose name will
19+
/// have the suffix `suffix`. If no directory can be created, None is returned.
20+
pub fn mkdtemp(tmpdir: &Path, suffix: &str) -> Option<Path> {
21+
let mut r = rand::rng();
22+
for _ in range(0u, 1000) {
23+
let p = tmpdir.push(r.gen_ascii_str(16) + suffix);
24+
if os::make_dir(&p, 0x1c0) { // 700
25+
return Some(p);
7326
}
7427
}
28+
None
7529
}
7630

7731
// the tests for this module need to change the path using change_dir,

0 commit comments

Comments
 (0)