From 860c44707ac9ee30e4955527fc928fa84eda3584 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Tue, 25 Jan 2022 09:07:56 +0100 Subject: [PATCH] awesomeness --- src/lib.rs | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 2915df9..71dc15e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,7 @@ +//! This crate provides a `GLock`, that is globally locked. Every `GLock` uses the same +//! global lock, so locking on will lock all. Sounds like a dumb idea? One of the most popular +//! programming implementations does it, so it must be smart. + use parking_lot::lock_api::{MutexGuard, RawMutex}; use parking_lot::Mutex; use std::cell::UnsafeCell; @@ -5,30 +9,44 @@ use std::ops::{Deref, DerefMut}; static LOCK: Mutex<()> = Mutex::const_new(RawMutex::INIT, ()); +/// A global lock that locks every `GLock` using the same global lock (like the GIL in cpython lmao) pub struct GLock { inner: UnsafeCell, } impl GLock { - pub fn lock(&self) -> GLockGuard { - let mutex_guard = LOCK.lock(); - // SAFETY: We have the global lock - let value = unsafe { &mut *self.inner.get() }; - GLockGuard { value, mutex_guard } + /// Creates a new GLock + pub const fn new(value: T) -> Self { + Self { + inner: UnsafeCell::new(value), + } } - pub fn get_mut(&mut self) -> &mut T { + /// Lock the global lock, not allowing any other `GLock` to be locked during the locked duration + pub fn lock(&self) -> GLockGuard { + let global_guard = LOCK.lock(); + // SAFETY: We took the global lock above, + // so no other one is allowed to get to this critical section here + let value = unsafe { &mut *self.inner.get() }; + GLockGuard { + value, + global_guard, + } + } + + pub const fn get_mut(&mut self) -> &mut T { self.inner.get_mut() } - pub fn into_inner(self) -> T { + pub const fn into_inner(self) -> T { self.inner.into_inner() } } +/// A guard that guards a globally locked value struct GLockGuard<'a, T> { value: &'a mut T, - mutex_guard: MutexGuard<'a, parking_lot::RawMutex, ()>, + global_guard: MutexGuard<'a, parking_lot::RawMutex, ()>, } impl<'a, T> Deref for GLockGuard<'a, T> {