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