#singleton #thread-safe

no-std singly

Lightweight "not" thread safe singleton but it depend on the usage though

1 unstable release

0.1.1 Mar 12, 2024
0.1.0 Mar 12, 2024

#347 in No standard library

MIT license

10KB
102 lines

Singly

Simple, Lighweight and "not" thread safe Singleton instance but it depend on the usage, consult the docs for more information regarding thread safety, feel free to make thread safe wrapper

Features

  • Set value to the instance with type.
  • Get reference value to the instance with type.
  • Get mutable reference value to the instance with type.
  • Work at no_std environment

Examples

fn main() {
   // Create the Singleton instance
   let mut instance = singly::Singleton::new();

   /// Set the i32 type to 12
   instance.set(12i32);

   /// Get mutable reference i32 type and set it to 14
   let a = instance.get_mut::<i32>();
   *a = 14;

   assert_eq!(instance.get::<i32>(), &14);

}

Installation

cargo add singly

License

This project is licensed under MIT


lib.rs:

Simple, Lighweight and "not" thread safe Singleton instance but it depend on the usage, feel free to make thread safe wrapper

Currently it can :

  • Set value to the instance with type.
  • Get reference value to the instance with type.
  • Get mutable reference value to the instance with type.
  • Work at no_std environment

Examples

fn main() {
   // Create the Singleton instance
   let mut instance = singly::Singleton::new();

   /// Set the i32 type to 12
   instance.set(12i32);

   /// Get mutable reference i32 type and set it to 14
   let a = instance.get_mut::<i32>();
   *a = 14;

   assert_eq!(instance.get::<i32>(), &14);

}

Some tips for Thread Safety

If none of this above not introduce it will definitely going to be data race

Examples Concurrent Situation

use std::{
    sync::{Arc, Mutex},
    thread::spawn,
};

use singly::Singleton;

struct Counter(i32);

// Notice on the type
type ArcMutexCounter = Arc<Mutex<Counter>>;

fn main() {
    let mut instance = Singleton::new();
    let counter = Arc::new(Mutex::new(Counter(0)));
    instance.set(counter);

    let mut handles = vec![];
    for _ in 0..10 {
        let counter_clone: ArcMutexCounter = Arc::clone(instance.get::<ArcMutexCounter>());
        let handle = spawn(move || {
            let mut counter = counter_clone.lock().unwrap();
            (*counter).0 += 1;
        });
        handles.push(handle);
    }

    let _ = handles
        .into_iter()
        .map(|handle| handle.join())
        .collect::<Result<Vec<_>, _>>();

    let counter = instance.get::<ArcMutexCounter>().lock().unwrap().0;
    assert_eq!(counter, 10);
}

There is example on integration_test.rs

Dependencies

~2MB
~27K SLoC