]> git.lizzy.rs Git - rust.git/blob - src/liballoc/arc.rs
auto merge of #14486 : michaelwoerister/rust/unified_enum_rep, r=luqmana
[rust.git] / src / liballoc / arc.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 /*!
12  * Concurrency-enabled mechanisms for sharing mutable and/or immutable state
13  * between tasks.
14  */
15
16 use core::atomics;
17 use core::clone::Clone;
18 use core::kinds::{Share, Send};
19 use core::mem::{min_align_of, size_of, drop};
20 use core::mem;
21 use core::ops::{Drop, Deref};
22 use core::option::{Some, None, Option};
23 use core::ptr;
24 use core::ptr::RawPtr;
25 use heap::deallocate;
26
27 /// An atomically reference counted wrapper for shared state.
28 ///
29 /// # Example
30 ///
31 /// In this example, a large vector of floats is shared between several tasks.
32 /// With simple pipes, without `Arc`, a copy would have to be made for each
33 /// task.
34 ///
35 /// ```rust
36 /// extern crate sync;
37 ///
38 /// use sync::Arc;
39 ///
40 /// fn main() {
41 ///     let numbers = Vec::from_fn(100, |i| i as f32);
42 ///     let shared_numbers = Arc::new(numbers);
43 ///
44 ///     for _ in range(0, 10) {
45 ///         let child_numbers = shared_numbers.clone();
46 ///
47 ///         spawn(proc() {
48 ///             let local_numbers = child_numbers.as_slice();
49 ///
50 ///             // Work with the local numbers
51 ///         });
52 ///     }
53 /// }
54 /// ```
55 #[unsafe_no_drop_flag]
56 pub struct Arc<T> {
57     // FIXME #12808: strange name to try to avoid interfering with
58     // field accesses of the contained type via Deref
59     _ptr: *mut ArcInner<T>,
60 }
61
62 /// A weak pointer to an `Arc`.
63 ///
64 /// Weak pointers will not keep the data inside of the `Arc` alive, and can be
65 /// used to break cycles between `Arc` pointers.
66 #[unsafe_no_drop_flag]
67 pub struct Weak<T> {
68     // FIXME #12808: strange name to try to avoid interfering with
69     // field accesses of the contained type via Deref
70     _ptr: *mut ArcInner<T>,
71 }
72
73 struct ArcInner<T> {
74     strong: atomics::AtomicUint,
75     weak: atomics::AtomicUint,
76     data: T,
77 }
78
79 impl<T: Share + Send> Arc<T> {
80     /// Create an atomically reference counted wrapper.
81     #[inline]
82     pub fn new(data: T) -> Arc<T> {
83         // Start the weak pointer count as 1 which is the weak pointer that's
84         // held by all the strong pointers (kinda), see std/rc.rs for more info
85         let x = box ArcInner {
86             strong: atomics::AtomicUint::new(1),
87             weak: atomics::AtomicUint::new(1),
88             data: data,
89         };
90         Arc { _ptr: unsafe { mem::transmute(x) } }
91     }
92
93     #[inline]
94     fn inner<'a>(&'a self) -> &'a ArcInner<T> {
95         // This unsafety is ok because while this arc is alive we're guaranteed
96         // that the inner pointer is valid. Furthermore, we know that the
97         // `ArcInner` structure itself is `Share` because the inner data is
98         // `Share` as well, so we're ok loaning out an immutable pointer to
99         // these contents.
100         unsafe { &*self._ptr }
101     }
102
103     /// Downgrades a strong pointer to a weak pointer
104     ///
105     /// Weak pointers will not keep the data alive. Once all strong references
106     /// to the underlying data have been dropped, the data itself will be
107     /// destroyed.
108     pub fn downgrade(&self) -> Weak<T> {
109         // See the clone() impl for why this is relaxed
110         self.inner().weak.fetch_add(1, atomics::Relaxed);
111         Weak { _ptr: self._ptr }
112     }
113 }
114
115 impl<T: Share + Send> Clone for Arc<T> {
116     /// Duplicate an atomically reference counted wrapper.
117     ///
118     /// The resulting two `Arc` objects will point to the same underlying data
119     /// object. However, one of the `Arc` objects can be sent to another task,
120     /// allowing them to share the underlying data.
121     #[inline]
122     fn clone(&self) -> Arc<T> {
123         // Using a relaxed ordering is alright here, as knowledge of the
124         // original reference prevents other threads from erroneously deleting
125         // the object.
126         //
127         // As explained in the [Boost documentation][1], Increasing the
128         // reference counter can always be done with memory_order_relaxed: New
129         // references to an object can only be formed from an existing
130         // reference, and passing an existing reference from one thread to
131         // another must already provide any required synchronization.
132         //
133         // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
134         self.inner().strong.fetch_add(1, atomics::Relaxed);
135         Arc { _ptr: self._ptr }
136     }
137 }
138
139 impl<T: Send + Share> Deref<T> for Arc<T> {
140     #[inline]
141     fn deref<'a>(&'a self) -> &'a T {
142         &self.inner().data
143     }
144 }
145
146 impl<T: Send + Share + Clone> Arc<T> {
147     /// Acquires a mutable pointer to the inner contents by guaranteeing that
148     /// the reference count is one (no sharing is possible).
149     ///
150     /// This is also referred to as a copy-on-write operation because the inner
151     /// data is cloned if the reference count is greater than one.
152     #[inline]
153     #[experimental]
154     pub fn make_unique<'a>(&'a mut self) -> &'a mut T {
155         if self.inner().strong.load(atomics::SeqCst) != 1 {
156             *self = Arc::new(self.deref().clone())
157         }
158         // This unsafety is ok because we're guaranteed that the pointer
159         // returned is the *only* pointer that will ever be returned to T. Our
160         // reference count is guaranteed to be 1 at this point, and we required
161         // the Arc itself to be `mut`, so we're returning the only possible
162         // reference to the inner data.
163         let inner = unsafe { &mut *self._ptr };
164         &mut inner.data
165     }
166 }
167
168 #[unsafe_destructor]
169 impl<T: Share + Send> Drop for Arc<T> {
170     fn drop(&mut self) {
171         // This structure has #[unsafe_no_drop_flag], so this drop glue may run
172         // more than once (but it is guaranteed to be zeroed after the first if
173         // it's run more than once)
174         if self._ptr.is_null() { return }
175
176         // Because `fetch_sub` is already atomic, we do not need to synchronize
177         // with other threads unless we are going to delete the object. This
178         // same logic applies to the below `fetch_sub` to the `weak` count.
179         if self.inner().strong.fetch_sub(1, atomics::Release) != 1 { return }
180
181         // This fence is needed to prevent reordering of use of the data and
182         // deletion of the data. Because it is marked `Release`, the
183         // decreasing of the reference count sychronizes with this `Acquire`
184         // fence. This means that use of the data happens before decreasing
185         // the refernce count, which happens before this fence, which
186         // happens before the deletion of the data.
187         //
188         // As explained in the [Boost documentation][1],
189         //
190         // It is important to enforce any possible access to the object in
191         // one thread (through an existing reference) to *happen before*
192         // deleting the object in a different thread. This is achieved by a
193         // "release" operation after dropping a reference (any access to the
194         // object through this reference must obviously happened before),
195         // and an "acquire" operation before deleting the object.
196         //
197         // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
198         atomics::fence(atomics::Acquire);
199
200         // Destroy the data at this time, even though we may not free the box
201         // allocation itself (there may still be weak pointers lying around).
202         unsafe { drop(ptr::read(&self.inner().data)); }
203
204         if self.inner().weak.fetch_sub(1, atomics::Release) == 1 {
205             atomics::fence(atomics::Acquire);
206             unsafe { deallocate(self._ptr as *mut u8, size_of::<ArcInner<T>>(),
207                                 min_align_of::<ArcInner<T>>()) }
208         }
209     }
210 }
211
212 impl<T: Share + Send> Weak<T> {
213     /// Attempts to upgrade this weak reference to a strong reference.
214     ///
215     /// This method will fail to upgrade this reference if the strong reference
216     /// count has already reached 0, but if there are still other active strong
217     /// references this function will return a new strong reference to the data
218     pub fn upgrade(&self) -> Option<Arc<T>> {
219         // We use a CAS loop to increment the strong count instead of a
220         // fetch_add because once the count hits 0 is must never be above 0.
221         let inner = self.inner();
222         loop {
223             let n = inner.strong.load(atomics::SeqCst);
224             if n == 0 { return None }
225             let old = inner.strong.compare_and_swap(n, n + 1, atomics::SeqCst);
226             if old == n { return Some(Arc { _ptr: self._ptr }) }
227         }
228     }
229
230     #[inline]
231     fn inner<'a>(&'a self) -> &'a ArcInner<T> {
232         // See comments above for why this is "safe"
233         unsafe { &*self._ptr }
234     }
235 }
236
237 impl<T: Share + Send> Clone for Weak<T> {
238     #[inline]
239     fn clone(&self) -> Weak<T> {
240         // See comments in Arc::clone() for why this is relaxed
241         self.inner().weak.fetch_add(1, atomics::Relaxed);
242         Weak { _ptr: self._ptr }
243     }
244 }
245
246 #[unsafe_destructor]
247 impl<T: Share + Send> Drop for Weak<T> {
248     fn drop(&mut self) {
249         // see comments above for why this check is here
250         if self._ptr.is_null() { return }
251
252         // If we find out that we were the last weak pointer, then its time to
253         // deallocate the data entirely. See the discussion in Arc::drop() about
254         // the memory orderings
255         if self.inner().weak.fetch_sub(1, atomics::Release) == 1 {
256             atomics::fence(atomics::Acquire);
257             unsafe { deallocate(self._ptr as *mut u8, size_of::<ArcInner<T>>(),
258                                 min_align_of::<ArcInner<T>>()) }
259         }
260     }
261 }
262
263 #[cfg(test)]
264 #[allow(experimental)]
265 mod tests {
266     use std::clone::Clone;
267     use std::comm::channel;
268     use std::mem::drop;
269     use std::ops::Drop;
270     use std::option::{Option, Some, None};
271     use std::sync::atomics;
272     use std::task;
273     use std::vec::Vec;
274     use super::{Arc, Weak};
275     use sync::Mutex;
276
277     struct Canary(*mut atomics::AtomicUint);
278
279     impl Drop for Canary
280     {
281         fn drop(&mut self) {
282             unsafe {
283                 match *self {
284                     Canary(c) => {
285                         (*c).fetch_add(1, atomics::SeqCst);
286                     }
287                 }
288             }
289         }
290     }
291
292     #[test]
293     fn manually_share_arc() {
294         let v = vec!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
295         let arc_v = Arc::new(v);
296
297         let (tx, rx) = channel();
298
299         task::spawn(proc() {
300             let arc_v: Arc<Vec<int>> = rx.recv();
301             assert_eq!(*arc_v.get(3), 4);
302         });
303
304         tx.send(arc_v.clone());
305
306         assert_eq!(*arc_v.get(2), 3);
307         assert_eq!(*arc_v.get(4), 5);
308
309         info!("{:?}", arc_v);
310     }
311
312     #[test]
313     fn test_cowarc_clone_make_unique() {
314         let mut cow0 = Arc::new(75u);
315         let mut cow1 = cow0.clone();
316         let mut cow2 = cow1.clone();
317
318         assert!(75 == *cow0.make_unique());
319         assert!(75 == *cow1.make_unique());
320         assert!(75 == *cow2.make_unique());
321
322         *cow0.make_unique() += 1;
323         *cow1.make_unique() += 2;
324         *cow2.make_unique() += 3;
325
326         assert!(76 == *cow0);
327         assert!(77 == *cow1);
328         assert!(78 == *cow2);
329
330         // none should point to the same backing memory
331         assert!(*cow0 != *cow1);
332         assert!(*cow0 != *cow2);
333         assert!(*cow1 != *cow2);
334     }
335
336     #[test]
337     fn test_cowarc_clone_unique2() {
338         let mut cow0 = Arc::new(75u);
339         let cow1 = cow0.clone();
340         let cow2 = cow1.clone();
341
342         assert!(75 == *cow0);
343         assert!(75 == *cow1);
344         assert!(75 == *cow2);
345
346         *cow0.make_unique() += 1;
347
348         assert!(76 == *cow0);
349         assert!(75 == *cow1);
350         assert!(75 == *cow2);
351
352         // cow1 and cow2 should share the same contents
353         // cow0 should have a unique reference
354         assert!(*cow0 != *cow1);
355         assert!(*cow0 != *cow2);
356         assert!(*cow1 == *cow2);
357     }
358
359     #[test]
360     fn test_live() {
361         let x = Arc::new(5);
362         let y = x.downgrade();
363         assert!(y.upgrade().is_some());
364     }
365
366     #[test]
367     fn test_dead() {
368         let x = Arc::new(5);
369         let y = x.downgrade();
370         drop(x);
371         assert!(y.upgrade().is_none());
372     }
373
374     #[test]
375     fn weak_self_cyclic() {
376         struct Cycle {
377             x: Mutex<Option<Weak<Cycle>>>
378         }
379
380         let a = Arc::new(Cycle { x: Mutex::new(None) });
381         let b = a.clone().downgrade();
382         *a.x.lock() = Some(b);
383
384         // hopefully we don't double-free (or leak)...
385     }
386
387     #[test]
388     fn drop_arc() {
389         let mut canary = atomics::AtomicUint::new(0);
390         let x = Arc::new(Canary(&mut canary as *mut atomics::AtomicUint));
391         drop(x);
392         assert!(canary.load(atomics::Acquire) == 1);
393     }
394
395     #[test]
396     fn drop_arc_weak() {
397         let mut canary = atomics::AtomicUint::new(0);
398         let arc = Arc::new(Canary(&mut canary as *mut atomics::AtomicUint));
399         let arc_weak = arc.downgrade();
400         assert!(canary.load(atomics::Acquire) == 0);
401         drop(arc);
402         assert!(canary.load(atomics::Acquire) == 1);
403         drop(arc_weak);
404     }
405 }