Struct ArcThreadShare

Source
pub struct ArcThreadShare<T> {
    pub data: Arc<AtomicPtr<T>>,
}
Expand description

Helper structure for working with Arc<AtomicPtr> directly (without locks!)

⚠️ WARNING: This structure has significant limitations and should be used with caution!

§Overview

ArcThreadShare<T> provides zero-copy data sharing between threads using atomic pointer operations. While this can offer high performance, it comes with important trade-offs that developers must understand.

§Key Features

  • Zero-Copy Operations: No data cloning during access
  • Atomic Updates: Uses atomic pointer operations
  • High Performance: Potentially faster than lock-based approaches
  • Memory Efficiency: Single copy of data shared across threads

§2. High Contention Performance Issues

Under high contention, many operations may be lost due to:

  • Box allocation/deallocation overhead
  • CAS failures requiring retries
  • Memory pressure from frequent allocations

§3. Memory Allocation Overhead

Every update operation involves Box allocation and deallocation.

§When to Use

  • Low-contention scenarios (few threads, infrequent updates)
  • Performance-critical applications where you understand the limitations
  • Simple atomic operations using built-in methods
  • Read-heavy workloads with occasional writes

§When to Avoid

  • High-frequency updates (>1000 ops/second per thread)
  • Critical data integrity requirements
  • Predictable performance needs
  • Large data structures

§Example

use thread_share::ArcThreadShare;

let counter = ArcThreadShare::new(0);

// Use atomic methods for safety
counter.increment();
counter.add(5);

assert_eq!(counter.get(), 6);

Fields§

§data: Arc<AtomicPtr<T>>

Implementations§

Source§

impl<T> ArcThreadShare<T>

Source

pub fn from_arc(arc: Arc<AtomicPtr<T>>) -> Self

Creates from Arc<AtomicPtr>

This method creates an ArcThreadShare<T> from an existing Arc<AtomicPtr<T>>. Useful when you already have atomic pointer data from other sources.

§Arguments
  • arc - An Arc<AtomicPtr<T>> containing the data to share
§Returns

A new ArcThreadShare<T> instance sharing the same data.

§Example
use thread_share::{share, ArcThreadShare};

let data = share!(String::from("Hello"));
let arc_data = data.as_arc();
let arc_share = ArcThreadShare::from_arc(arc_data);

// Now you can use atomic operations
arc_share.update(|s| s.push_str(" World"));
Source

pub fn new(data: T) -> Self
where T: Clone,

Creates a new ArcThreadShare with data

This method creates a new ArcThreadShare<T> instance with the provided data. The data is boxed and converted to an atomic pointer for thread-safe sharing.

§Arguments
  • data - The initial data to share between threads
§Requirements

The type T must implement Clone trait.

§Returns

A new ArcThreadShare<T> instance containing the data.

§Example
use thread_share::ArcThreadShare;

let counter = ArcThreadShare::new(0);
let message = ArcThreadShare::new(String::from("Hello"));
let data = ArcThreadShare::new(vec![1, 2, 3]);
Source

pub fn get(&self) -> T
where T: Clone,

Gets a copy of data

This method retrieves a copy of the current data. The operation is safe but involves cloning the data.

§Requirements

The type T must implement Clone trait.

§Returns

A copy of the current data.

§Example
use thread_share::ArcThreadShare;

let counter = ArcThreadShare::new(42);
let value = counter.get();
assert_eq!(value, 42);
Source

pub fn set(&self, new_data: T)

Sets data atomically

This method atomically replaces the current data with new data. The old data is automatically deallocated.

§Arguments
  • new_data - The new data to set
§Example
use thread_share::ArcThreadShare;

let counter = ArcThreadShare::new(0);
counter.set(100);
assert_eq!(counter.get(), 100);
Source

pub fn update<F>(&self, f: F)
where F: FnOnce(&mut T),

Updates data (⚠️ NOT atomic for complex operations!)

⚠️ WARNING: This method is NOT atomic for complex operations!

For simple operations like += 1, use the atomic methods increment() or add() instead. This method can cause race conditions under high contention.

§Arguments
  • f - Closure that receives a mutable reference to the data
§Example
use thread_share::ArcThreadShare;

let counter = ArcThreadShare::new(0);

// ❌ NOT atomic - can cause race conditions
counter.update(|x| *x += 1);

// ✅ Use atomic methods instead
counter.increment();
Source

pub fn increment(&self)
where T: Copy + Add<Output = T> + AddAssign + From<u8> + 'static,

Atomically increments numeric values (for types that support it)

This method provides atomic increment operations for numeric types. It uses a compare-exchange loop to ensure atomicity.

§Requirements

The type T must implement:

  • Copy - for efficient copying
  • std::ops::Add<Output = T> - for addition operations
  • std::ops::AddAssign - for compound assignment
  • From<u8> - for creating the value 1
  • 'static - for lifetime requirements
§Example
use thread_share::ArcThreadShare;

let counter = ArcThreadShare::new(0);

// Atomic increment
counter.increment();
assert_eq!(counter.get(), 1);

counter.increment();
assert_eq!(counter.get(), 2);
Source

pub fn add(&self, value: T)
where T: Copy + Add<Output = T> + AddAssign + 'static,

Atomically adds a value (for types that support it)

Source

pub fn read<F, R>(&self, f: F) -> R
where F: FnOnce(&T) -> R,

Reads data

Source

pub fn write<F, R>(&self, f: F) -> R
where F: FnOnce(&mut T) -> R,

Writes data

Source

pub fn to_json(&self) -> Result<String, Error>
where T: Serialize + Clone,

Source

pub fn from_json<D>(&self, json: &str) -> Result<D, Error>

Trait Implementations§

Source§

impl<T> Clone for ArcThreadShare<T>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T> Send for ArcThreadShare<T>

Source§

impl<T> Sync for ArcThreadShare<T>

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.