Sfoglia il codice sorgente

add a `Mutex` version for some type not impl `Sync`.

ZRY 7 mesi fa
parent
commit
74446224d5
3 ha cambiato i file con 120 aggiunte e 4 eliminazioni
  1. 1 1
      Cargo.toml
  2. 50 2
      src/lib.rs
  3. 69 1
      src/tokio/mod.rs

+ 1 - 1
Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "simple-rw-global"
-version = "0.4.0"
+version = "0.5.0"
 edition = "2021"
 authors = ["ZRY <admin@>z-touhou.org"]
 

+ 50 - 2
src/lib.rs

@@ -3,6 +3,8 @@
 //!
 //! This crate is AS IS.
 //!
+//! NOTE: `GlobalContainer` use `RWLock`, `GlobalMutexContainer` use `Mutex`.
+//!
 //! By ZRY.
 //!
 //! # Features
@@ -67,7 +69,7 @@ pub mod tokio;
 
 use std::ops::{Deref, DerefMut};
 #[cfg(feature = "stdsync")]
-use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
+use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard, Mutex, MutexGuard};
 
 pub enum GOption<T> {
     None,
@@ -139,4 +141,50 @@ impl<T> Drop for GlobalContainer<T> {
     fn drop(&mut self) {
         self.manual_drop();
     }
-}
+}
+
+#[cfg(feature = "stdsync")]
+pub struct GlobalMutexContainer<T>
+{
+    content: Mutex<GOption<T>>,
+}
+
+#[cfg(feature = "stdsync")]
+impl<T> GlobalMutexContainer<T> {
+    pub const fn new() -> GlobalMutexContainer<T> {
+        GlobalMutexContainer::<T>{
+            content: Mutex::new(GOption::None),
+        }
+    }
+
+    pub fn set(&self, obj: T) {
+        *self.content.lock().unwrap() = GOption::Some(obj);
+    }
+
+    pub fn is_empty(&self) -> bool {
+        let v = self.content.lock().unwrap();
+        match v.deref() {
+            GOption::None => true,
+            GOption::Some(_) => false,
+        }
+    }
+
+    pub fn manual_drop(&self) {
+        *self.content.lock().unwrap() = GOption::None;
+    }
+
+    pub fn get(&self) -> MutexGuard<GOption<T>> {
+        self.content.lock().unwrap()
+    }
+
+    pub fn get_mut(&self) -> MutexGuard<GOption<T>> {
+        self.content.lock().unwrap()
+    }
+}
+
+#[cfg(feature = "stdsync")]
+impl<T> Drop for GlobalMutexContainer<T> {
+    fn drop(&mut self) {
+        self.manual_drop();
+    }
+}

+ 69 - 1
src/tokio/mod.rs

@@ -1,5 +1,7 @@
 //! Async version for `tokio`, need feature `tokio`.
 //!
+//! NOTE: `AsyncGlobalContainer` use `RWLock`, `AsyncGlobalMutexContainer` use `Mutex`.
+//!
 //! `lazy_static!` should be used for `AsyncGlobalContainer::new()`,
 //! because of `tokio::sync::RwLock::new()` is not a constant function.
 //!
@@ -65,7 +67,7 @@
 
 use std::ops::Deref;
 #[cfg(feature = "tokio")]
-use tokio::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
+use tokio::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard, Mutex, MutexGuard};
 use crate::GOption;
 
 
@@ -134,3 +136,69 @@ impl<T> Drop for AsyncGlobalContainer<T> {
         self.manual_drop();
     }
 }
+
+#[cfg(feature = "tokio")]
+pub struct AsyncMutexGlobalContainer<T>
+{
+    content: Mutex<GOption<T>>,
+}
+
+#[cfg(feature = "tokio")]
+impl<T> AsyncMutexGlobalContainer<T> {
+    pub fn new() -> AsyncMutexGlobalContainer<T> {
+        AsyncMutexGlobalContainer::<T>{
+            content: Mutex::new(GOption::None),
+        }
+    }
+
+    pub async fn set(&self, obj: T) {
+        *self.content.lock().await = GOption::Some(obj);
+    }
+
+    pub fn blocking_set(&self, obj: T) {
+        *self.content.blocking_lock() = GOption::Some(obj);
+    }
+
+    pub async fn is_empty(&self) -> bool {
+        let v = self.content.lock().await;
+        match v.deref() {
+            GOption::None => true,
+            GOption::Some(_) => false,
+        }
+    }
+
+    pub fn is_empty_blocking(&self) -> bool {
+        let v = self.content.blocking_lock();
+        match v.deref() {
+            GOption::None => true,
+            GOption::Some(_) => false,
+        }
+    }
+
+    pub fn manual_drop(&self) {
+        *self.content.blocking_lock() = GOption::None;
+    }
+
+    pub async fn get(&self) -> MutexGuard<GOption<T>> {
+        self.content.lock().await
+    }
+
+    pub async fn get_mut(&self) -> MutexGuard<GOption<T>> {
+        self.content.lock().await
+    }
+
+    pub fn blocking_get(&self) -> MutexGuard<GOption<T>> {
+        self.content.blocking_lock()
+    }
+
+    pub fn blocking_get_mut(&self) -> MutexGuard<GOption<T>> {
+        self.content.blocking_lock()
+    }
+}
+
+#[cfg(feature = "tokio")]
+impl<T> Drop for AsyncMutexGlobalContainer<T> {
+    fn drop(&mut self) {
+        self.manual_drop();
+    }
+}