#![stable(feature = "rust1", since = "1.0.0")]
-//! Threadsafe reference-counted boxes (the `Arc<T>` type).
+//! Thread-safe reference-counting pointers.
//!
-//! The `Arc<T>` type provides shared ownership of an immutable value through
-//! atomic reference counting.
+//! See the [`Arc<T>`][arc] documentation for more details.
//!
-//! `Weak<T>` is a weak reference to the `Arc<T>` box, and it is created by
-//! the `downgrade` method.
-//! # Examples
-//!
-//! Sharing some immutable data between threads:
-//!
-// Note that we **do not** run these tests here. The windows builders get super
-// unhappy of a thread outlives the main thread and then exits at the same time
-// (something deadlocks) so we just avoid this entirely by not running these
-// tests.
-//! ```no_run
-//! use std::sync::Arc;
-//! use std::thread;
-//!
-//! let five = Arc::new(5);
-//!
-//! for _ in 0..10 {
-//! let five = five.clone();
-//!
-//! thread::spawn(move || {
-//! println!("{:?}", five);
-//! });
-//! }
-//! ```
+//! [arc]: struct.Arc.html
use boxed::Box;
use core::convert::From;
use heap::deallocate;
+/// A soft limit on the amount of references that may be made to an `Arc`.
+///
+/// Going above this limit will abort your program (although not
+/// necessarily) at _exactly_ `MAX_REFCOUNT + 1` references.
const MAX_REFCOUNT: usize = (isize::MAX) as usize;
-/// An atomically reference counted wrapper for shared state.
-/// Destruction is deterministic, and will occur as soon as the last owner is
-/// gone. It is marked as `Send` because it uses atomic reference counting.
+/// A thread-safe reference-counting pointer.
///
-/// If you do not need thread-safety, and just need shared ownership, consider
-/// the [`Rc<T>` type](../rc/struct.Rc.html). It is the same as `Arc<T>`, but
-/// does not use atomics, making it both thread-unsafe as well as significantly
-/// faster when updating the reference count.
+/// The type `Arc<T>` provides shared ownership of a value of type `T`,
+/// allocated in the heap. Invoking [`clone`][clone] on `Arc` produces
+/// a new pointer to the same value in the heap. When the last `Arc`
+/// pointer to a given value is destroyed, the pointed-to value is
+/// also destroyed.
///
-/// Note: the inherent methods defined on `Arc<T>` are all associated functions,
-/// which means that you have to call them as e.g. `Arc::get_mut(&value)`
-/// instead of `value.get_mut()`. This is so that there are no conflicts with
-/// methods on the inner type `T`, which are what you want to call in the
-/// majority of cases.
+/// Shared references in Rust disallow mutation by default, and `Arc` is no
+/// exception. If you need to mutate through an `Arc`, use [`Mutex`][mutex],
+/// [`RwLock`][rwlock], or one of the [`Atomic`][atomic] types.
///
-/// # Examples
+/// `Arc` uses atomic operations for reference counting, so `Arc`s can be
+/// sent between threads. In other words, `Arc<T>` implements [`Send`][send]
+/// as long as `T` implements `Send` and [`Sync`][sync]. The disadvantage is
+/// that atomic operations are more expensive than ordinary memory accesses.
+/// If you are not sharing reference-counted values between threads, consider
+/// using [`rc::Rc`][rc] for lower overhead. `Rc` is a safe default, because
+/// the compiler will catch any attempt to send an `Rc` between threads.
+/// However, a library might choose `Arc` in order to give library consumers
+/// more flexibility.
///
-/// In this example, a large vector of data will be shared by several threads. First we
-/// wrap it with a `Arc::new` and then clone the `Arc<T>` reference for every thread (which will
-/// increase the reference count atomically).
+/// The [`downgrade`][downgrade] method can be used to create a non-owning
+/// [`Weak`][weak] pointer. A `Weak` pointer can be [`upgrade`][upgrade]d
+/// to an `Arc`, but this will return [`None`][option] if the value has
+/// already been dropped.
+///
+/// A cycle between `Arc` pointers will never be deallocated. For this reason,
+/// `Weak` is used to break cycles. For example, a tree could have strong
+/// `Arc` pointers from parent nodes to children, and `Weak` pointers from
+/// children back to their parents.
+///
+/// `Arc<T>` automatically dereferences to `T` (via the [`Deref`][deref] trait),
+/// so you can call `T`'s methods on a value of type `Arc<T>`. To avoid name
+/// clashes with `T`'s methods, the methods of `Arc<T>` itself are [associated
+/// functions][assoc], called using function-like syntax:
///
/// ```
/// use std::sync::Arc;
-/// use std::thread;
+/// let my_arc = Arc::new(());
///
-/// fn main() {
-/// let numbers: Vec<_> = (0..100).collect();
-/// let shared_numbers = Arc::new(numbers);
+/// Arc::downgrade(&my_arc);
+/// ```
///
-/// for _ in 0..10 {
-/// // prepare a copy of reference here and it will be moved to the thread
-/// let child_numbers = shared_numbers.clone();
+/// `Weak<T>` does not auto-dereference to `T`, because the value may have
+/// already been destroyed.
///
-/// thread::spawn(move || {
-/// let local_numbers = &child_numbers[..];
+/// [arc]: struct.Arc.html
+/// [weak]: struct.Weak.html
+/// [rc]: ../../std/rc/struct.Rc.html
+/// [clone]: ../../std/clone/trait.Clone.html#tymethod.clone
+/// [mutex]: ../../std/sync/struct.Mutex.html
+/// [rwlock]: ../../std/sync/struct.RwLock.html
+/// [atomic]: ../../std/sync/atomic/index.html
+/// [send]: ../../std/marker/trait.Send.html
+/// [sync]: ../../std/marker/trait.Sync.html
+/// [deref]: ../../std/ops/trait.Deref.html
+/// [downgrade]: struct.Arc.html#method.downgrade
+/// [upgrade]: struct.Weak.html#method.upgrade
+/// [option]: ../../std/option/enum.Option.html
+/// [assoc]: ../../book/method-syntax.html#associated-functions
///
-/// // Work with the local numbers
-/// });
-/// }
-/// }
-/// ```
-/// You can also share mutable data between threads safely
-/// by putting it inside `Mutex` and then share `Mutex` immutably
-/// with `Arc<T>` as shown below.
+/// # Examples
///
-// See comment at the top of this file for why the test is no_run
+/// Sharing some immutable data between threads:
+///
+// Note that we **do not** run these tests here. The windows builders get super
+// unhappy if a thread outlives the main thread and then exits at the same time
+// (something deadlocks) so we just avoid this entirely by not running these
+// tests.
/// ```no_run
-/// use std::sync::{Arc, Mutex};
+/// use std::sync::Arc;
/// use std::thread;
///
-/// let five = Arc::new(Mutex::new(5));
+/// let five = Arc::new(5);
///
/// for _ in 0..10 {
/// let five = five.clone();
///
/// thread::spawn(move || {
-/// let mut number = five.lock().unwrap();
+/// println!("{:?}", five);
+/// });
+/// }
+/// ```
///
-/// *number += 1;
+/// Sharing a mutable `AtomicUsize`:
///
-/// println!("{}", *number); // prints 6
+/// ```no_run
+/// use std::sync::Arc;
+/// use std::sync::atomic::{AtomicUsize, Ordering};
+/// use std::thread;
+///
+/// let val = Arc::new(AtomicUsize::new(5));
+///
+/// for _ in 0..10 {
+/// let val = val.clone();
+///
+/// thread::spawn(move || {
+/// let v = val.fetch_add(1, Ordering::SeqCst);
+/// println!("{:?}", v);
/// });
/// }
/// ```
-
-#[cfg_attr(stage0, unsafe_no_drop_flag)]
+///
+/// See the [`rc` documentation][rc_examples] for more examples of reference
+/// counting in general.
+///
+/// [rc_examples]: ../../std/rc/index.html#examples
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Arc<T: ?Sized> {
ptr: Shared<ArcInner<T>>,
#[unstable(feature = "coerce_unsized", issue = "27732")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {}
-/// A weak pointer to an `Arc`.
+/// A weak version of [`Arc`][arc].
///
-/// Weak pointers will not keep the data inside of the `Arc` alive, and can be
-/// used to break cycles between `Arc` pointers.
+/// `Weak` pointers do not count towards determining if the inner value
+/// should be dropped.
///
-/// A `Weak<T>` pointer can be upgraded to an `Arc<T>` pointer, but
-/// will return `None` if the value has already been dropped.
+/// The typical way to obtain a `Weak` pointer is to call
+/// [`Arc::downgrade`][downgrade].
///
-/// For example, a tree with parent pointers can be represented by putting the
-/// nodes behind strong `Arc<T>` pointers, and then storing the parent pointers
-/// as `Weak<T>` pointers.
-
-#[cfg_attr(stage0, unsafe_no_drop_flag)]
+/// See the [`Arc`][arc] documentation for more details.
+///
+/// [arc]: struct.Arc.html
+/// [downgrade]: struct.Arc.html#method.downgrade
#[stable(feature = "arc_weak", since = "1.4.0")]
pub struct Weak<T: ?Sized> {
ptr: Shared<ArcInner<T>>,
Arc { ptr: unsafe { Shared::new(Box::into_raw(x)) } }
}
- /// Unwraps the contained value if the `Arc<T>` has exactly one strong reference.
+ /// Returns the contained value, if the `Arc` has exactly one strong reference.
///
- /// Otherwise, an `Err` is returned with the same `Arc<T>`.
+ /// Otherwise, an [`Err`][result] is returned with the same `Arc` that was
+ /// passed in.
///
/// This will succeed even if there are outstanding weak references.
///
+ /// [result]: ../../std/result/enum.Result.html
+ ///
/// # Examples
///
/// ```
///
/// let x = Arc::new(4);
/// let _y = x.clone();
- /// assert_eq!(Arc::try_unwrap(x), Err(Arc::new(4)));
+ /// assert_eq!(*Arc::try_unwrap(x).unwrap_err(), 4);
/// ```
#[inline]
#[stable(feature = "arc_unique", since = "1.4.0")]
}
impl<T: ?Sized> Arc<T> {
- /// Downgrades the `Arc<T>` to a `Weak<T>` reference.
+ /// Creates a new [`Weak`][weak] pointer to this value.
+ ///
+ /// [weak]: struct.Weak.html
///
/// # Examples
///
}
}
- /// Get the number of weak references to this value.
+ /// Gets the number of [`Weak`][weak] pointers to this value.
+ ///
+ /// Be careful how you use this information, because another thread
+ /// may change the weak count at any time.
+ ///
+ /// [weak]: struct.Weak.html
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(arc_counts)]
+ ///
+ /// use std::sync::Arc;
+ ///
+ /// let five = Arc::new(5);
+ /// let _weak_five = Arc::downgrade(&five);
+ ///
+ /// // This assertion is deterministic because we haven't shared
+ /// // the `Arc` or `Weak` between threads.
+ /// assert_eq!(1, Arc::weak_count(&five));
+ /// ```
#[inline]
#[unstable(feature = "arc_counts", reason = "not clearly useful, and racy",
issue = "28356")]
this.inner().weak.load(SeqCst) - 1
}
- /// Get the number of strong references to this value.
+ /// Gets the number of strong (`Arc`) pointers to this value.
+ ///
+ /// Be careful how you use this information, because another thread
+ /// may change the strong count at any time.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(arc_counts)]
+ ///
+ /// use std::sync::Arc;
+ ///
+ /// let five = Arc::new(5);
+ /// let _also_five = five.clone();
+ ///
+ /// // This assertion is deterministic because we haven't shared
+ /// // the `Arc` between threads.
+ /// assert_eq!(2, Arc::strong_count(&five));
+ /// ```
#[inline]
#[unstable(feature = "arc_counts", reason = "not clearly useful, and racy",
issue = "28356")]
#[unstable(feature = "ptr_eq",
reason = "newly added",
issue = "36497")]
- /// Return whether two `Arc` references point to the same value
- /// (not just values that compare equal).
+ /// Returns true if the two `Arc`s point to the same value (not
+ /// just values that compare as equal).
///
/// # Examples
///
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Clone for Arc<T> {
- /// Makes a clone of the `Arc<T>`.
+ /// Makes a clone of the `Arc` pointer.
///
- /// This increases the strong reference count.
+ /// This creates another pointer to the same inner value, increasing the
+ /// strong reference count.
///
/// # Examples
///
}
impl<T: Clone> Arc<T> {
- /// Make a mutable reference into the given `Arc<T>`.
- /// If the `Arc<T>` has more than one strong reference, or any weak
- /// references, the inner data is cloned.
+ /// Makes a mutable reference into the given `Arc`.
+ ///
+ /// If there are other `Arc` or [`Weak`][weak] pointers to the same value,
+ /// then `make_mut` will invoke [`clone`][clone] on the inner value to
+ /// ensure unique ownership. This is also referred to as clone-on-write.
///
- /// This is also referred to as a copy-on-write.
+ /// See also [`get_mut`][get_mut], which will fail rather than cloning.
+ ///
+ /// [weak]: struct.Weak.html
+ /// [clone]: ../../std/clone/trait.Clone.html#tymethod.clone
+ /// [get_mut]: struct.Arc.html#method.get_mut
///
/// # Examples
///
/// *Arc::make_mut(&mut data) += 1; // Won't clone anything
/// *Arc::make_mut(&mut other_data) *= 2; // Won't clone anything
///
- /// // Note: data and other_data now point to different numbers
+ /// // Now `data` and `other_data` point to different values.
/// assert_eq!(*data, 8);
/// assert_eq!(*other_data, 12);
- ///
/// ```
#[inline]
#[stable(feature = "arc_unique", since = "1.4.0")]
}
impl<T: ?Sized> Arc<T> {
- /// Returns a mutable reference to the contained value if the `Arc<T>` has
- /// one strong reference and no weak references.
+ /// Returns a mutable reference to the inner value, if there are
+ /// no other `Arc` or [`Weak`][weak] pointers to the same value.
+ ///
+ /// Returns [`None`][option] otherwise, because it is not safe to
+ /// mutate a shared value.
+ ///
+ /// See also [`make_mut`][make_mut], which will [`clone`][clone]
+ /// the inner value when it's shared.
+ ///
+ /// [weak]: struct.Weak.html
+ /// [option]: ../../std/option/enum.Option.html
+ /// [make_mut]: struct.Arc.html#method.make_mut
+ /// [clone]: ../../std/clone/trait.Clone.html#tymethod.clone
///
/// # Examples
///
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Drop for Arc<T> {
- /// Drops the `Arc<T>`.
+ /// Drops the `Arc`.
///
/// This will decrement the strong reference count. If the strong reference
- /// count becomes zero and the only other references are `Weak<T>` ones,
- /// `drop`s the inner value.
+ /// count reaches zero then the only other references (if any) are
+ /// [`Weak`][weak], so we `drop` the inner value.
+ ///
+ /// [weak]: struct.Weak.html
///
/// # Examples
///
/// ```
/// use std::sync::Arc;
///
- /// {
- /// let five = Arc::new(5);
- ///
- /// // stuff
+ /// struct Foo;
///
- /// drop(five); // explicit drop
+ /// impl Drop for Foo {
+ /// fn drop(&mut self) {
+ /// println!("dropped!");
+ /// }
/// }
- /// {
- /// let five = Arc::new(5);
///
- /// // stuff
+ /// let foo = Arc::new(Foo);
+ /// let foo2 = foo.clone();
///
- /// } // implicit drop
+ /// drop(foo); // Doesn't print anything
+ /// drop(foo2); // Prints "dropped!"
/// ```
#[unsafe_destructor_blind_to_params]
#[inline]
}
impl<T> Weak<T> {
- /// Constructs a new `Weak<T>` without an accompanying instance of T.
+ /// Constructs a new `Weak<T>`, without an accompanying instance of `T`.
///
- /// This allocates memory for T, but does not initialize it. Calling
- /// Weak<T>::upgrade() on the return value always gives None.
+ /// This allocates memory for `T`, but does not initialize it. Calling
+ /// [`upgrade`][upgrade] on the return value always gives
+ /// [`None`][option].
+ ///
+ /// [upgrade]: struct.Weak.html#method.upgrade
+ /// [option]: ../../std/option/enum.Option.html
///
/// # Examples
///
/// use std::sync::Weak;
///
/// let empty: Weak<i64> = Weak::new();
+ /// assert!(empty.upgrade().is_none());
/// ```
#[stable(feature = "downgraded_weak", since = "1.10.0")]
pub fn new() -> Weak<T> {
}
impl<T: ?Sized> Weak<T> {
- /// Upgrades a weak reference to a strong reference.
+ /// Upgrades the `Weak` pointer to an [`Arc`][arc], if possible.
///
- /// Upgrades the `Weak<T>` reference to an `Arc<T>`, if possible.
+ /// Returns [`None`][option] if the strong count has reached zero and the
+ /// inner value was destroyed.
///
- /// Returns `None` if there were no strong references and the data was
- /// destroyed.
+ /// [arc]: struct.Arc.html
+ /// [option]: ../../std/option/enum.Option.html
///
/// # Examples
///
/// let weak_five = Arc::downgrade(&five);
///
/// let strong_five: Option<Arc<_>> = weak_five.upgrade();
+ /// assert!(strong_five.is_some());
+ ///
+ /// // Destroy all strong pointers.
+ /// drop(strong_five);
+ /// drop(five);
+ ///
+ /// assert!(weak_five.upgrade().is_none());
/// ```
#[stable(feature = "arc_weak", since = "1.4.0")]
pub fn upgrade(&self) -> Option<Arc<T>> {
#[stable(feature = "arc_weak", since = "1.4.0")]
impl<T: ?Sized> Clone for Weak<T> {
- /// Makes a clone of the `Weak<T>`.
+ /// Makes a clone of the `Weak` pointer.
///
- /// This increases the weak reference count.
+ /// This creates another pointer to the same inner value, increasing the
+ /// weak reference count.
///
/// # Examples
///
#[stable(feature = "downgraded_weak", since = "1.10.0")]
impl<T> Default for Weak<T> {
- /// Constructs a new `Weak<T>` without an accompanying instance of T.
+ /// Constructs a new `Weak<T>`, without an accompanying instance of `T`.
+ ///
+ /// This allocates memory for `T`, but does not initialize it. Calling
+ /// [`upgrade`][upgrade] on the return value always gives
+ /// [`None`][option].
+ ///
+ /// [upgrade]: struct.Weak.html#method.upgrade
+ /// [option]: ../../std/option/enum.Option.html
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::sync::Weak;
+ ///
+ /// let empty: Weak<i64> = Default::default();
+ /// assert!(empty.upgrade().is_none());
+ /// ```
fn default() -> Weak<T> {
Weak::new()
}
#[stable(feature = "arc_weak", since = "1.4.0")]
impl<T: ?Sized> Drop for Weak<T> {
- /// Drops the `Weak<T>`.
+ /// Drops the `Weak` pointer.
///
/// This will decrement the weak reference count.
///
/// ```
/// use std::sync::Arc;
///
- /// {
- /// let five = Arc::new(5);
- /// let weak_five = Arc::downgrade(&five);
- ///
- /// // stuff
+ /// struct Foo;
///
- /// drop(weak_five); // explicit drop
+ /// impl Drop for Foo {
+ /// fn drop(&mut self) {
+ /// println!("dropped!");
+ /// }
/// }
- /// {
- /// let five = Arc::new(5);
- /// let weak_five = Arc::downgrade(&five);
///
- /// // stuff
+ /// let foo = Arc::new(Foo);
+ /// let weak_foo = Arc::downgrade(&foo);
+ /// let other_weak_foo = weak_foo.clone();
///
- /// } // implicit drop
+ /// drop(weak_foo); // Doesn't print anything
+ /// drop(foo); // Prints "dropped!"
+ ///
+ /// assert!(other_weak_foo.upgrade().is_none());
/// ```
fn drop(&mut self) {
let ptr = *self.ptr;
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + PartialEq> PartialEq for Arc<T> {
- /// Equality for two `Arc<T>`s.
+ /// Equality for two `Arc`s.
///
- /// Two `Arc<T>`s are equal if their inner value are equal.
+ /// Two `Arc`s are equal if their inner values are equal.
///
/// # Examples
///
///
/// let five = Arc::new(5);
///
- /// five == Arc::new(5);
+ /// assert!(five == Arc::new(5));
/// ```
fn eq(&self, other: &Arc<T>) -> bool {
*(*self) == *(*other)
}
- /// Inequality for two `Arc<T>`s.
+ /// Inequality for two `Arc`s.
///
- /// Two `Arc<T>`s are unequal if their inner value are unequal.
+ /// Two `Arc`s are unequal if their inner values are unequal.
///
/// # Examples
///
///
/// let five = Arc::new(5);
///
- /// five != Arc::new(5);
+ /// assert!(five != Arc::new(6));
/// ```
fn ne(&self, other: &Arc<T>) -> bool {
*(*self) != *(*other)
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + PartialOrd> PartialOrd for Arc<T> {
- /// Partial comparison for two `Arc<T>`s.
+ /// Partial comparison for two `Arc`s.
///
/// The two are compared by calling `partial_cmp()` on their inner values.
///
///
/// ```
/// use std::sync::Arc;
+ /// use std::cmp::Ordering;
///
/// let five = Arc::new(5);
///
- /// five.partial_cmp(&Arc::new(5));
+ /// assert_eq!(Some(Ordering::Less), five.partial_cmp(&Arc::new(6)));
/// ```
fn partial_cmp(&self, other: &Arc<T>) -> Option<Ordering> {
(**self).partial_cmp(&**other)
}
- /// Less-than comparison for two `Arc<T>`s.
+ /// Less-than comparison for two `Arc`s.
///
/// The two are compared by calling `<` on their inner values.
///
///
/// let five = Arc::new(5);
///
- /// five < Arc::new(5);
+ /// assert!(five < Arc::new(6));
/// ```
fn lt(&self, other: &Arc<T>) -> bool {
*(*self) < *(*other)
}
- /// 'Less-than or equal to' comparison for two `Arc<T>`s.
+ /// 'Less than or equal to' comparison for two `Arc`s.
///
/// The two are compared by calling `<=` on their inner values.
///
///
/// let five = Arc::new(5);
///
- /// five <= Arc::new(5);
+ /// assert!(five <= Arc::new(5));
/// ```
fn le(&self, other: &Arc<T>) -> bool {
*(*self) <= *(*other)
}
- /// Greater-than comparison for two `Arc<T>`s.
+ /// Greater-than comparison for two `Arc`s.
///
/// The two are compared by calling `>` on their inner values.
///
///
/// let five = Arc::new(5);
///
- /// five > Arc::new(5);
+ /// assert!(five > Arc::new(4));
/// ```
fn gt(&self, other: &Arc<T>) -> bool {
*(*self) > *(*other)
}
- /// 'Greater-than or equal to' comparison for two `Arc<T>`s.
+ /// 'Greater than or equal to' comparison for two `Arc`s.
///
/// The two are compared by calling `>=` on their inner values.
///
///
/// let five = Arc::new(5);
///
- /// five >= Arc::new(5);
+ /// assert!(five >= Arc::new(5));
/// ```
fn ge(&self, other: &Arc<T>) -> bool {
*(*self) >= *(*other)
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + Ord> Ord for Arc<T> {
+ /// Comparison for two `Arc`s.
+ ///
+ /// The two are compared by calling `cmp()` on their inner values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::sync::Arc;
+ /// use std::cmp::Ordering;
+ ///
+ /// let five = Arc::new(5);
+ ///
+ /// assert_eq!(Ordering::Less, five.cmp(&Arc::new(6)));
+ /// ```
fn cmp(&self, other: &Arc<T>) -> Ordering {
(**self).cmp(&**other)
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Default> Default for Arc<T> {
- /// Creates a new `Arc<T>`, with the `Default` value for T.
+ /// Creates a new `Arc<T>`, with the `Default` value for `T`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::sync::Arc;
+ ///
+ /// let x: Arc<i32> = Default::default();
+ /// assert_eq!(*x, 0);
+ /// ```
fn default() -> Arc<T> {
Arc::new(Default::default())
}
}
#[test]
+ #[cfg_attr(target_os = "emscripten", ignore)]
fn manually_share_arc() {
let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let arc_v = Arc::new(v);