sync_2 1.0.4

A little crate providing a Rust implemented Mutex and RwLock.
Documentation
#![feature(negative_impls)]
#![allow(clippy::comparison_chain)]
#![allow(unused, dead_code)]

mod non_thread_local {
use core::cell::UnsafeCell;
use core::ops::{Deref, DerefMut};
use core::sync::atomic::{spin_loop_hint as spin_loop, AtomicU8, AtomicUsize, Ordering::SeqCst};

use std::io::{self, BufRead, Read, Seek, SeekFrom, Write};
use std::sync::{
    LockResult, PoisonError,
    TryLockError::{Poisoned, WouldBlock},
    TryLockResult,
};
use std::thread::panicking;

use std::sync::atomic::Ordering::Relaxed;
use thread_local::ThreadLocal;

// sentinel most significant bit,write lock
const WRITE: usize = usize::MAX - (usize::MAX / 2);
// sentinel pen-most significant bit,poisoned state
const POISON: usize = WRITE / 2;

const LOCK: u8 = 2;
const POISON_M: u8 = 1;


/// An allocation-free [`Mutex`][`std::sync::Mutex`] made in pure Rust.
pub struct Mutex<T> {
    value: UnsafeCell<T>,
    ref_count: AtomicU8,
}

unsafe impl<T: Send> Send for Mutex<T> {}
unsafe impl<T: Send> Sync for Mutex<T> {}

impl<T> Mutex<T> {
    /// Creates a new mutex in an unlocked state ready for use.
    ///
    /// This function it's constant only without `debug_assertions` due to declare a thread local
    /// storage to avoid acquire the lock twice from the same thread.
    #[inline]
    pub const fn new(x: T) -> Self {
        Self {
            value: UnsafeCell::new(x),
            ref_count: AtomicU8::new(0),
        }
    }

    /// Acquires a mutex, blocking the current thread until it is able to do so.
    ///
    /// This function will block the local thread until it is available to acquire
    /// the mutex. Upon returning, the thread is the only thread with the lock
    /// held. An RAII guard is returned to allow scoped unlock of the lock. When
    /// the guard goes out of scope, the mutex will be unlocked.
    ///
    /// The exact behavior on locking a mutex in the thread which already holds
    /// the lock is left unspecified. However, this function will not return on
    /// the second call (it might panic or deadlock, for example).
    ///
    /// # Errors
    ///
    /// If another user of this mutex panicked while holding the mutex, then
    /// this call will return an error once the mutex is acquired.
    ///
    /// # Panics
    ///
    /// This function might panic when called if the lock is already held by
    /// the current thread only with `debug_assertions`.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::sync::Arc;
    /// use sync_2::Mutex;
    /// use std::thread;
    ///
    /// let mutex = Arc::new(Mutex::new(0));
    /// let c_mutex = mutex.clone();
    ///
    /// thread::spawn(move || {
    ///     *c_mutex.lock().unwrap() = 10;
    /// }).join().expect("thread::spawn failed");
    /// assert_eq!(*mutex.lock().unwrap(), 10);
    /// ```
    #[inline]
    pub fn lock(&self) -> LockResult<MutexGuard<'_, T>> {
        loop {
            match self.try_lock() {
                Ok(e) => break Ok(e),
                Err(WouldBlock) => spin_loop(),
                Err(Poisoned(e)) => break Err(e),
            }
        }
    }

    /// Attempts to acquire this lock.
    ///
    /// If the lock could not be acquired at this time, then [`Err`] is returned.
    /// Otherwise, an RAII guard is returned. The lock will be unlocked when the
    /// guard is dropped.
    ///
    /// This function does not block.
    ///
    /// # Errors
    ///
    /// If another user of this mutex panicked while holding the mutex, then
    /// this call will return failure if the mutex would otherwise be
    /// acquired.
    ///
    /// [`Err`]: ../../std/result/enum.Result.html#variant.Err
    ///
    /// # Examples
    ///
    /// ```
    /// use std::sync::Arc;
    /// use sync_2::Mutex;
    /// use std::thread;
    ///
    /// let mutex = Arc::new(Mutex::new(0));
    /// let c_mutex = mutex.clone();
    ///
    /// thread::spawn(move || {
    ///     let mut lock = c_mutex.try_lock();
    ///     if let Ok(ref mut mutex) = lock {
    ///         **mutex = 10;
    ///     } else {
    ///         println!("try_lock failed");
    ///     }
    /// }).join().expect("thread::spawn failed");
    /// assert_eq!(*mutex.lock().unwrap(), 10);
    /// ```
    pub fn try_lock(&self) -> TryLockResult<MutexGuard<'_, T>> {
        let x = match self.ref_count.fetch_update(
            SeqCst,
            SeqCst,
            |x| if x < LOCK { Some(x | LOCK) } else { None },
        ) {
            Ok(x) => x,
            Err(_) => return Err(WouldBlock),
        };

        if x < POISON_M {
            Ok(MutexGuard { lock: self })
        } else {
            Err(Poisoned(PoisonError::new(MutexGuard { lock: self })))
        }
    }

    /// Determines whether the mutex is poisoned.
    ///
    /// If another thread is active, the mutex can still become poisoned at any
    /// time. You should not trust a `false` value for program correctness
    /// without additional synchronization.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::sync::Arc;
    /// use sync_2::Mutex;
    /// use std::thread;
    ///
    /// let mutex = Arc::new(Mutex::new(0));
    /// let c_mutex = mutex.clone();
    ///
    /// let _ = thread::spawn(move || {
    ///     let _lock = c_mutex.lock().unwrap();
    ///     panic!(); // the mutex gets poisoned
    /// }).join();
    /// assert_eq!(mutex.is_poisoned(), true);
    /// ```
    #[inline]
    pub fn is_poisoned(&self) -> bool {
        (self.ref_count.load(SeqCst) & POISON_M) == POISON_M
    }

    /// Returns a mutable reference to the underlying data.
    ///
    /// Since this call borrows the `Mutex` mutably, no actual locking needs to
    /// take place -- the mutable borrow statically guarantees no locks exist.
    ///
    /// # Errors
    ///
    /// If another user of this mutex panicked while holding the mutex, then
    /// this call will return an error instead.
    ///
    /// # Examples
    ///
    /// ```
    /// use sync_2::Mutex;
    ///
    /// let mut mutex = Mutex::new(0);
    /// *mutex.get_mut().unwrap() = 10;
    /// assert_eq!(*mutex.lock().unwrap(), 10);
    /// ```
    #[inline]
    pub fn get_mut(&mut self) -> LockResult<&mut T> {
        let x = unsafe { &mut *self.value.get() };

        if self.is_poisoned() {
            Err(PoisonError::new(x))
        } else {
            Ok(x)
        }
    }

    /// Consumes this mutex, returning the underlying data.
    ///
    /// # Errors
    ///
    /// If another user of this mutex panicked while holding the mutex, then
    /// this call will return an error instead.
    ///
    /// # Examples
    ///
    /// ```
    /// use sync_2::Mutex;
    ///
    /// let mutex = Mutex::new(0);
    /// assert_eq!(mutex.into_inner().unwrap(), 0);
    /// ```
    #[inline]
    pub fn into_inner(self) -> LockResult<T> {
        if self.is_poisoned() {
            Err(PoisonError::new(self.value.into_inner()))
        } else {
            Ok(self.value.into_inner())
        }
    }
}

impl<T> !Send for MutexGuard<'_, T> {}
unsafe impl<T: Sync> Sync for MutexGuard<'_, T> {}

/// Unique guard created by the method [`Mutex::lock`] and [`Mutex::try_lock`].
pub struct MutexGuard<'a, T> {
    lock: &'a Mutex<T>,
}

impl<'a, T> Deref for MutexGuard<'a, T> {
    type Target = T;

    #[inline]
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.lock.value.get() }
    }
}

impl<'a, T> DerefMut for MutexGuard<'a, T> {
    #[inline]
    fn deref_mut(&mut self) -> &mut Self::Target {
        unsafe { &mut *self.lock.value.get() }
    }
}

impl<'a, T> Drop for MutexGuard<'a, T> {
    #[inline]
    fn drop(&mut self) {
        if panicking() {
            self.lock.ref_count.fetch_or(POISON_M, SeqCst);
        }
        self.lock.ref_count.fetch_sub(LOCK, SeqCst);
    }
}

impl<'a, T: Seek> Seek for MutexGuard<'a, T> {
    #[inline]
    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
        (**self).seek(pos)
    }
}

impl<'a, T: Write> Write for MutexGuard<'a, T> {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        (**self).write(buf)
    }

    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        (**self).flush()
    }
}

impl<'a, T: Read> Read for MutexGuard<'a, T> {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        (**self).read(buf)
    }
}

impl<'a, T: BufRead> BufRead for MutexGuard<'a, T> {
    #[inline]
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        (**self).fill_buf()
    }

    #[inline]
    fn consume(&mut self, amt: usize) {
        (**self).consume(amt)
    }
}

impl<'a, T: AsRef<U>, U> AsRef<U> for MutexGuard<'a, T> {
    fn as_ref(&self) -> &U {
        (**self).as_ref()
    }
}

impl<'a, T: AsMut<U>, U> AsMut<U> for MutexGuard<'a, T> {
    fn as_mut(&mut self) -> &mut U {
        (**self).as_mut()
    }
}

    

/// An allocation-free [`RwLock`][`std::sync::RwLock`] made in pure Rust.
pub struct RwLock<T> {
    value: UnsafeCell<T>,
    ref_count: AtomicUsize,
}

unsafe impl<T: Send> Send for RwLock<T> {}
unsafe impl<T: Send> Sync for RwLock<T> {}

impl<T> RwLock<T> {
    /// Creates a new `RwLock` locking the value `x`.
    ///
    /// This function it's constant only without `debug_assertions` due to declare a thread local
    /// storage to avoid acquire the lock twice from the same thread.
    #[inline]
    pub const fn new(x: T) -> Self {
        Self {
            value: UnsafeCell::new(x),
            ref_count: AtomicUsize::new(0),
        }
    }

    /// Locks this rwlock with shared read access, blocking the current thread
    /// until it can be acquired.
    ///
    /// The calling thread will be blocked until there are no more writers which
    /// hold the lock. There may be other readers currently inside the lock when
    /// this method returns. This method does not provide any guarantees with
    /// respect to the ordering of whether contentious readers or writers will
    /// acquire the lock first.
    ///
    /// Returns an RAII guard which will release this thread's shared access
    /// once it is dropped.
    ///
    /// # Errors
    ///
    /// This function will return an error if the `RwLock` is poisoned. An `RwLock`
    /// is poisoned whenever a writer panics while holding an exclusive lock.
    /// The failure will occur immediately after the lock has been acquired.
    ///
    /// # Panics
    ///
    /// This function panic when called if the lock is already held by the current thread with `debug_assertions` on.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::sync::Arc;
    /// use std::thread;
    /// use sync_2::RwLock;
    ///
    /// let lock = Arc::new(RwLock::new(1));
    /// let c_lock = lock.clone();
    ///
    /// let n = lock.read().unwrap();
    /// assert_eq!(*n, 1);
    ///
    /// thread::spawn(move || {
    ///     let r = c_lock.read();
    ///     assert!(r.is_ok());
    /// }).join().unwrap();
    /// ```
    #[inline]
    pub fn read(&self) -> LockResult<SharedGuard<'_, T>> {
        loop {
            match self.try_read() {
                Ok(e) => break Ok(e),
                Err(WouldBlock) => spin_loop(),
                Err(Poisoned(e)) => break Err(e),
            }
        }
    }

    /// Locks this rwlock with exclusive write access, blocking the current
    /// thread until it can be acquired.
    ///
    /// This function will not return while other writers or other readers
    /// currently have access to the lock.
    ///
    /// Returns an RAII guard which will drop the write access of this rwlock
    /// when dropped.
    ///
    /// # Errors
    ///
    /// This function will return an error if the `RwLock` is poisoned. An `RwLock`
    /// is poisoned whenever a writer panics while holding an exclusive lock.
    /// An error will be returned when the lock is acquired.
    ///
    /// # Panics
    ///
    /// This function panic when called if the lock is already held by the current thread with `debug_assertions` on.
    ///
    /// # Examples
    ///
    /// ```
    /// use sync_2::RwLock;
    ///
    /// let lock = RwLock::new(1);
    ///
    /// let mut n = lock.write().unwrap();
    /// *n = 2;
    ///
    /// assert!(lock.try_read().is_err());
    /// ```
    #[inline]
    pub fn write(&self) -> LockResult<UniqueGuard<'_, T>> {
        loop {
            match self.try_write() {
                Ok(e) => break Ok(e),
                Err(WouldBlock) => spin_loop(),
                Err(Poisoned(e)) => break Err(e),
            }
        }
    }

    /// Attempts to acquire this rwlock with shared read access.
    ///
    /// If the access could not be granted at this time, then `Err` is returned.
    /// Otherwise, an RAII guard is returned which will release the shared access
    /// when it is dropped.
    ///
    /// This function does not block.
    ///
    /// This function does not provide any guarantees with respect to the ordering
    /// of whether contentious readers or writers will acquire the lock first.
    ///
    /// # Errors
    ///
    /// This function will return an error if the `RwLock` is poisoned. An `RwLock`
    /// is poisoned whenever a writer panics while holding an exclusive lock. An
    /// error will only be returned if the lock would have otherwise been
    /// acquired.
    ///
    /// # Examples
    ///
    /// ```
    /// use sync_2::RwLock;
    ///
    /// let lock = RwLock::new(1);
    ///
    /// match lock.try_read() {
    ///     Ok(n) => assert_eq!(*n, 1),
    ///     Err(_) => unreachable!(),
    /// };
    /// ```
    pub fn try_read(&self) -> TryLockResult<SharedGuard<'_, T>> {
        let x = match self.ref_count.fetch_update(
            SeqCst,
            SeqCst,
            |x| if x < WRITE { Some(x + 1) } else { None },
        ) {
            Ok(x) => x,
            Err(_) => return Err(WouldBlock),
        };

        // WRITE it's greater than poison,once we know our value it's less than WRITE it is ok to not filter bits as in `is_poisoned`
        if x < POISON {
            Ok(SharedGuard { lock: self })
        } else {
            Err(Poisoned(PoisonError::new(SharedGuard { lock: self })))
        }
    }

    /// Attempts to lock this rwlock with exclusive write access.
    ///
    /// If the lock could not be acquired at this time, then `Err` is returned.
    /// Otherwise, an RAII guard is returned which will release the lock when
    /// it is dropped.
    ///
    /// This function does not block.
    ///
    /// This function does not provide any guarantees with respect to the ordering
    /// of whether contentious readers or writers will acquire the lock first.
    ///
    /// # Errors
    ///
    /// This function will return an error if the `RwLock` is poisoned. An `RwLock`
    /// is poisoned whenever a writer panics while holding an exclusive lock. An
    /// error will only be returned if the lock would have otherwise been
    /// acquired.
    ///
    /// # Examples
    ///
    /// ```
    /// use sync_2::RwLock;
    ///
    /// let lock = RwLock::new(1);
    ///
    /// let n = lock.read().unwrap();
    /// assert_eq!(*n, 1);
    ///
    /// println!("{:?}", lock);
    /// assert!(lock.try_write().is_err());
    /// ```
    pub fn try_write(&self) -> TryLockResult<UniqueGuard<'_, T>> {
        let mut clean = true;

        match self.ref_count.fetch_update(
            SeqCst,
            SeqCst,
            |x| {
                if x == 0 || {
                    clean = false;
                    x == POISON
                } {
                    Some(x | WRITE)
                } else {
                    None
                }
            },
        ) {
            Ok(x) => x,
            Err(_) => return Err(WouldBlock),
        };

        if clean {
            Ok(UniqueGuard { lock: self })
        } else {
            Err(Poisoned(PoisonError::new(UniqueGuard { lock: self })))
        }
    }

    /// Determines whether the lock is poisoned.
    ///
    /// If another thread is active, the lock can still become poisoned at any
    /// time. You should not trust a `false` value for program correctness
    /// without additional synchronization.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::sync::Arc;
    /// use std::thread;
    /// use sync_2::RwLock;
    ///
    /// let lock = Arc::new(RwLock::new(0));
    /// let c_lock = lock.clone();
    ///
    /// let _ = thread::spawn(move || {
    ///     let _lock = c_lock.write().unwrap();
    ///     panic!(); // the lock gets poisoned
    /// }).join();
    /// assert_eq!(lock.is_poisoned(), true);
    /// ```
    #[inline]
    pub fn is_poisoned(&self) -> bool {
        (self.ref_count.load(SeqCst) & POISON) == POISON
    }

    /// Returns a mutable reference to the underlying data.
    ///
    /// Since this call borrows the `RwLock` mutably, no actual locking needs to
    /// take place -- the mutable borrow statically guarantees no locks exist.
    ///
    /// # Errors
    ///
    /// This function will return an error if the `RwLock` is poisoned. An `RwLock`
    /// is poisoned whenever a writer panics while holding an exclusive lock. An
    /// error will only be returned if the lock would have otherwise been
    /// acquired.
    ///
    /// # Examples
    ///
    /// ```
    /// use sync_2::RwLock;
    ///
    /// let mut lock = RwLock::new(0);
    /// *lock.get_mut().unwrap() = 10;
    /// assert_eq!(*lock.read().unwrap(), 10);
    /// ```
    #[inline]
    pub fn get_mut(&mut self) -> LockResult<&mut T> {
        let x = unsafe { &mut *self.value.get() };

        if self.is_poisoned() {
            Err(PoisonError::new(x))
        } else {
            Ok(x)
        }
    }

    /// Consumes this `RwLock`, returning the underlying data.
    ///
    /// # Errors
    ///
    /// This function will return an error if the `RwLock` is poisoned. An `RwLock`
    /// is poisoned whenever a writer panics while holding an exclusive lock. An
    /// error will only be returned if the lock would have otherwise been
    /// acquired.
    ///
    /// # Examples
    ///
    /// ```
    /// use sync_2::RwLock;
    ///
    /// let lock = RwLock::new(String::new());
    /// {
    ///     let mut s = lock.write().unwrap();
    ///     *s = "modified".to_owned();
    /// }
    /// assert_eq!(lock.into_inner().unwrap(), "modified");
    /// ```
    #[inline]
    pub fn into_inner(self) -> LockResult<T> {
        if self.is_poisoned() {
            Err(PoisonError::new(self.value.into_inner()))
        } else {
            Ok(self.value.into_inner())
        }
    }
}

use core::fmt;

impl<T: fmt::Debug> fmt::Debug for RwLock<T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self.try_read() {
            Ok(guard) => f.debug_struct("RwLock").field("data", &&*guard).finish(),
            Err(Poisoned(err)) => f
                .debug_struct("RwLock")
                .field("data", &&**err.get_ref())
                .finish(),
            Err(WouldBlock) => {
                struct LockedPlaceholder;
                impl fmt::Debug for LockedPlaceholder {
                    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                        f.write_str("<locked>")
                    }
                }

                f.debug_struct("RwLock")
                    .field("data", &LockedPlaceholder)
                    .finish()
            }
        }
    }
}

impl<T: Default> Default for RwLock<T> {
    /// Creates a new `RwLock<T>`, with the `Default` value for T.
    fn default() -> Self {
        Self::new(T::default())
    }
}

impl<T> From<T> for RwLock<T> {
    /// Creates a new instance of an `RwLock<T>` which is unlocked.
    /// This is equivalent to [`RwLock::new`].
    ///
    /// [`RwLock::new`]: #method.new
    fn from(t: T) -> Self {
        Self::new(t)
    }
}

/// Read-only shared guard created by the methods [`RwLock::read`] and [`RwLock::try_read`].
/// 
/// Leaking this struct would cause deadlock with any further call to [`RwLock::write`].
pub struct SharedGuard<'a, T> {
    lock: &'a RwLock<T>,
}

impl<T: fmt::Debug> fmt::Debug for SharedGuard<'_, T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("RwLockReadGuard")
            .field("lock", self.lock)
            .finish()
    }
}

impl<T: fmt::Display> fmt::Display for SharedGuard<'_, T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        (**self).fmt(f)
    }
}

impl<T: fmt::Debug> fmt::Debug for UniqueGuard<'_, T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("RwLockWriteGuard")
            .field("lock", self.lock)
            .finish()
    }
}

impl<T: fmt::Display> fmt::Display for UniqueGuard<'_, T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        (**self).fmt(f)
    }
}

impl<'a, T> Drop for SharedGuard<'a, T> {
    #[inline]
    fn drop(&mut self) {
        self.lock.ref_count.fetch_sub(1, SeqCst);
    }
}

impl<'a, T> Deref for SharedGuard<'a, T> {
    type Target = T;

    #[inline]
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.lock.value.get() }
    }
}

impl<T> !Send for SharedGuard<'_, T> {}
unsafe impl<T: Sync> Sync for SharedGuard<'_, T> {}

impl<T> !Send for UniqueGuard<'_, T> {}
unsafe impl<T: Sync> Sync for UniqueGuard<'_, T> {}

/// Unique guard created by the methods [`RwLock::write`] and [`RwLock::try_write`].
/// 
/// Leaking this struct would cause deadlock with any further call to [`RwLock::write`] or [`RwLock::read`].
pub struct UniqueGuard<'a, T> {
    lock: &'a RwLock<T>,
}

impl<'a, T> Deref for UniqueGuard<'a, T> {
    type Target = T;

    #[inline]
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.lock.value.get() }
    }
}

impl<'a, T> DerefMut for UniqueGuard<'a, T> {
    #[inline]
    fn deref_mut(&mut self) -> &mut Self::Target {
        unsafe { &mut *self.lock.value.get() }
    }
}

impl<'a, T> Drop for UniqueGuard<'a, T> {
    #[inline]
    fn drop(&mut self) {
        if panicking() {
            self.lock.ref_count.fetch_or(POISON, SeqCst);
        }
        self.lock.ref_count.fetch_xor(WRITE, SeqCst);
    }
}

impl<'a, T: Seek> Seek for UniqueGuard<'a, T> {
    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
        (**self).seek(pos)
    }
}

impl<'a, T: Write> Write for UniqueGuard<'a, T> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        (**self).write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        (**self).flush()
    }
}

impl<'a, T: Read> Read for UniqueGuard<'a, T> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        (**self).read(buf)
    }
}

impl<'a, T: BufRead> BufRead for UniqueGuard<'a, T> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        (**self).fill_buf()
    }

    fn consume(&mut self, amt: usize) {
        (**self).consume(amt)
    }
}
}


mod thread_local_a {
use core::cell::UnsafeCell;
use core::ops::{Deref, DerefMut};
use core::sync::atomic::{spin_loop_hint as spin_loop, AtomicU8, AtomicUsize, Ordering::SeqCst};

use std::io::{self, BufRead, Read, Seek, SeekFrom, Write};
use std::sync::{
    LockResult, PoisonError,
    TryLockError::{Poisoned, WouldBlock},
    TryLockResult,
};
use std::thread::panicking;

use std::sync::atomic::Ordering::Relaxed;
use thread_local::ThreadLocal;

use super::non_thread_local;


// sentinel most significant bit,write lock
const WRITE: usize = usize::MAX - (usize::MAX / 2);
// sentinel pen-most significant bit,poisoned state
const POISON: usize = WRITE / 2;

/// An allocation-free [`RwLock`][`std::sync::RwLock`] made in pure Rust.
pub struct RwLock<T> {
    value: UnsafeCell<T>,
    ref_count: AtomicUsize,
    local_ref_count: non_thread_local::Mutex<Option<ThreadLocal<AtomicUsize>>>,
}

unsafe impl<T: Send> Send for RwLock<T> {}
unsafe impl<T: Send> Sync for RwLock<T> {}

impl<T> RwLock<T> {

    /// Creates a new `RwLock` locking the value `x`.
    #[inline]
    pub const fn new(x: T) -> Self {
        Self {
            value: UnsafeCell::new(x),
            ref_count: AtomicUsize::new(0),
            local_ref_count: non_thread_local::Mutex::new(None),
        }
    }

    /// Locks this rwlock with shared read access, blocking the current thread
    /// until it can be acquired.
    ///
    /// The calling thread will be blocked until there are no more writers which
    /// hold the lock. There may be other readers currently inside the lock when
    /// this method returns. This method does not provide any guarantees with
    /// respect to the ordering of whether contentious readers or writers will
    /// acquire the lock first.
    ///
    /// Returns an RAII guard which will release this thread's shared access
    /// once it is dropped.
    ///
    /// # Errors
    ///
    /// This function will return an error if the `RwLock` is poisoned. An `RwLock`
    /// is poisoned whenever a writer panics while holding an exclusive lock.
    /// The failure will occur immediately after the lock has been acquired.
    ///
    /// # Panics
    ///
    /// This function panic when called if the lock is already held by the current thread with `debug_assertions` on.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::sync::Arc;
    /// use std::thread;
    /// use sync_2::RwLock;
    ///
    /// let lock = Arc::new(RwLock::new(1));
    /// let c_lock = lock.clone();
    ///
    /// let n = lock.read().unwrap();
    /// assert_eq!(*n, 1);
    ///
    /// thread::spawn(move || {
    ///     let r = c_lock.read();
    ///     assert!(r.is_ok());
    /// }).join().unwrap();
    /// ```
    #[inline]
    pub fn read(&self) -> LockResult<SharedGuard<'_, T>> {
        let mut x = self.local_ref_count.lock().unwrap();

        if x.get_or_insert_with(ThreadLocal::new).get_or(|| AtomicUsize::new(0)).load(Relaxed) >= WRITE {
            panic!("rwlock read lock would result in deadlock")
        }

        x.get_or_insert_with(ThreadLocal::new).get_or(|| AtomicUsize::new(0)).fetch_add(1, Relaxed);

        loop {
            match self.try_read() {
                Ok(e) => break Ok(e),
                Err(WouldBlock) => spin_loop(),
                Err(Poisoned(e)) => break Err(e),
            }
        }
    }

    /// Locks this rwlock with exclusive write access, blocking the current
    /// thread until it can be acquired.
    ///
    /// This function will not return while other writers or other readers
    /// currently have access to the lock.
    ///
    /// Returns an RAII guard which will drop the write access of this rwlock
    /// when dropped.
    ///
    /// # Errors
    ///
    /// This function will return an error if the `RwLock` is poisoned. An `RwLock`
    /// is poisoned whenever a writer panics while holding an exclusive lock.
    /// An error will be returned when the lock is acquired.
    ///
    /// # Panics
    ///
    /// This function panic when called if the lock is already held by the current thread with `debug_assertions` on.
    ///
    /// # Examples
    ///
    /// ```
    /// use sync_2::RwLock;
    ///
    /// let lock = RwLock::new(1);
    ///
    /// let mut n = lock.write().unwrap();
    /// *n = 2;
    ///
    /// assert!(lock.try_read().is_err());
    /// ```
    #[inline]
    pub fn write(&self) -> LockResult<UniqueGuard<'_, T>> {
        let mut x = self.local_ref_count.lock().unwrap();

        if x.get_or_insert_with(ThreadLocal::new).get_or(|| AtomicUsize::new(0)).load(Relaxed) != 0 {
            panic!("rwlock read lock would result in deadlock")
        }

        x.get_or_insert_with(ThreadLocal::new).get_or(|| AtomicUsize::new(0)).fetch_or(WRITE, Relaxed);

        loop {
            match self.try_write() {
                Ok(e) => break Ok(e),
                Err(WouldBlock) => spin_loop(),
                Err(Poisoned(e)) => break Err(e),
            }
        }
    }

    /// Attempts to acquire this rwlock with shared read access.
    ///
    /// If the access could not be granted at this time, then `Err` is returned.
    /// Otherwise, an RAII guard is returned which will release the shared access
    /// when it is dropped.
    ///
    /// This function does not block.
    ///
    /// This function does not provide any guarantees with respect to the ordering
    /// of whether contentious readers or writers will acquire the lock first.
    ///
    /// # Errors
    ///
    /// This function will return an error if the `RwLock` is poisoned. An `RwLock`
    /// is poisoned whenever a writer panics while holding an exclusive lock. An
    /// error will only be returned if the lock would have otherwise been
    /// acquired.
    ///
    /// # Examples
    ///
    /// ```
    /// use sync_2::RwLock;
    ///
    /// let lock = RwLock::new(1);
    ///
    /// match lock.try_read() {
    ///     Ok(n) => assert_eq!(*n, 1),
    ///     Err(_) => unreachable!(),
    /// };
    /// ```
    pub fn try_read(&self) -> TryLockResult<SharedGuard<'_, T>> {
        let x = match self.ref_count.fetch_update(
            SeqCst,
            SeqCst,
            |x| if x < WRITE { Some(x + 1) } else { None },
        ) {
            Ok(x) => x,
            Err(_) => return Err(WouldBlock),
        };

        // WRITE it's greater than poison,once we know our value it's less than WRITE it is ok to not filter bits as in `is_poisoned`
        if x < POISON {
            Ok(SharedGuard { lock: self })
        } else {
            Err(Poisoned(PoisonError::new(SharedGuard { lock: self })))
        }
    }

    /// Attempts to lock this rwlock with exclusive write access.
    ///
    /// If the lock could not be acquired at this time, then `Err` is returned.
    /// Otherwise, an RAII guard is returned which will release the lock when
    /// it is dropped.
    ///
    /// This function does not block.
    ///
    /// This function does not provide any guarantees with respect to the ordering
    /// of whether contentious readers or writers will acquire the lock first.
    ///
    /// # Errors
    ///
    /// This function will return an error if the `RwLock` is poisoned. An `RwLock`
    /// is poisoned whenever a writer panics while holding an exclusive lock. An
    /// error will only be returned if the lock would have otherwise been
    /// acquired.
    ///
    /// # Examples
    ///
    /// ```
    /// use sync_2::RwLock;
    ///
    /// let lock = RwLock::new(1);
    ///
    /// let n = lock.read().unwrap();
    /// assert_eq!(*n, 1);
    ///
    /// println!("{:?}", lock);
    /// assert!(lock.try_write().is_err());
    /// ```
    pub fn try_write(&self) -> TryLockResult<UniqueGuard<'_, T>> {
        let mut clean = true;

        match self.ref_count.fetch_update(
            SeqCst,
            SeqCst,
            |x| {
                if x == 0 || {
                    clean = false;
                    x == POISON
                } {
                    Some(x | WRITE)
                } else {
                    None
                }
            },
        ) {
            Ok(x) => x,
            Err(_) => return Err(WouldBlock),
        };

        if clean {
            Ok(UniqueGuard { lock: self })
        } else {
            Err(Poisoned(PoisonError::new(UniqueGuard { lock: self })))
        }
    }

    /// Determines whether the lock is poisoned.
    ///
    /// If another thread is active, the lock can still become poisoned at any
    /// time. You should not trust a `false` value for program correctness
    /// without additional synchronization.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::sync::Arc;
    /// use std::thread;
    /// use sync_2::RwLock;
    ///
    /// let lock = Arc::new(RwLock::new(0));
    /// let c_lock = lock.clone();
    ///
    /// let _ = thread::spawn(move || {
    ///     let _lock = c_lock.write().unwrap();
    ///     panic!(); // the lock gets poisoned
    /// }).join();
    /// assert_eq!(lock.is_poisoned(), true);
    /// ```
    #[inline]
    pub fn is_poisoned(&self) -> bool {
        (self.ref_count.load(SeqCst) & POISON) == POISON
    }

    /// Returns a mutable reference to the underlying data.
    ///
    /// Since this call borrows the `RwLock` mutably, no actual locking needs to
    /// take place -- the mutable borrow statically guarantees no locks exist.
    ///
    /// # Errors
    ///
    /// This function will return an error if the `RwLock` is poisoned. An `RwLock`
    /// is poisoned whenever a writer panics while holding an exclusive lock. An
    /// error will only be returned if the lock would have otherwise been
    /// acquired.
    ///
    /// # Examples
    ///
    /// ```
    /// use sync_2::RwLock;
    ///
    /// let mut lock = RwLock::new(0);
    /// *lock.get_mut().unwrap() = 10;
    /// assert_eq!(*lock.read().unwrap(), 10);
    /// ```
    #[inline]
    pub fn get_mut(&mut self) -> LockResult<&mut T> {
        let x = unsafe { &mut *self.value.get() };

        if self.is_poisoned() {
            Err(PoisonError::new(x))
        } else {
            Ok(x)
        }
    }

    /// Consumes this `RwLock`, returning the underlying data.
    ///
    /// # Errors
    ///
    /// This function will return an error if the `RwLock` is poisoned. An `RwLock`
    /// is poisoned whenever a writer panics while holding an exclusive lock. An
    /// error will only be returned if the lock would have otherwise been
    /// acquired.
    ///
    /// # Examples
    ///
    /// ```
    /// use sync_2::RwLock;
    ///
    /// let lock = RwLock::new(String::new());
    /// {
    ///     let mut s = lock.write().unwrap();
    ///     *s = "modified".to_owned();
    /// }
    /// assert_eq!(lock.into_inner().unwrap(), "modified");
    /// ```
    #[inline]
    pub fn into_inner(self) -> LockResult<T> {
        if self.is_poisoned() {
            Err(PoisonError::new(self.value.into_inner()))
        } else {
            Ok(self.value.into_inner())
        }
    }
}

use core::fmt;

impl<T: fmt::Debug> fmt::Debug for RwLock<T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self.try_read() {
            Ok(guard) => f.debug_struct("RwLock").field("data", &&*guard).finish(),
            Err(Poisoned(err)) => f
                .debug_struct("RwLock")
                .field("data", &&**err.get_ref())
                .finish(),
            Err(WouldBlock) => {
                struct LockedPlaceholder;
                impl fmt::Debug for LockedPlaceholder {
                    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                        f.write_str("<locked>")
                    }
                }

                f.debug_struct("RwLock")
                    .field("data", &LockedPlaceholder)
                    .finish()
            }
        }
    }
}

impl<T: Default> Default for RwLock<T> {
    /// Creates a new `RwLock<T>`, with the `Default` value for T.
    fn default() -> Self {
        Self::new(T::default())
    }
}

impl<T> From<T> for RwLock<T> {
    /// Creates a new instance of an `RwLock<T>` which is unlocked.
    /// This is equivalent to [`RwLock::new`].
    ///
    /// [`RwLock::new`]: #method.new
    fn from(t: T) -> Self {
        Self::new(t)
    }
}

/// Read-only shared guard created by the methods [`RwLock::read`] and [`RwLock::try_read`].
/// 
/// Leaking this struct would cause deadlock with any further call to [`RwLock::write`].
pub struct SharedGuard<'a, T> {
    lock: &'a RwLock<T>,
}

impl<T: fmt::Debug> fmt::Debug for SharedGuard<'_, T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("RwLockReadGuard")
            .field("lock", self.lock)
            .finish()
    }
}

impl<T: fmt::Display> fmt::Display for SharedGuard<'_, T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        (**self).fmt(f)
    }
}

impl<T: fmt::Debug> fmt::Debug for UniqueGuard<'_, T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("RwLockWriteGuard")
            .field("lock", self.lock)
            .finish()
    }
}

impl<T: fmt::Display> fmt::Display for UniqueGuard<'_, T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        (**self).fmt(f)
    }
}

impl<'a, T> Drop for SharedGuard<'a, T> {
    #[inline]
    fn drop(&mut self) {
        self.lock.ref_count.fetch_sub(1, SeqCst);
        self.lock
            .local_ref_count.lock().unwrap().get_or_insert_with(ThreadLocal::new)
            .get_or(|| AtomicUsize::new(0))
            .fetch_sub(1, Relaxed);
    }
}

impl<'a, T> Deref for SharedGuard<'a, T> {
    type Target = T;

    #[inline]
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.lock.value.get() }
    }
}

impl<T> !Send for SharedGuard<'_, T> {}
unsafe impl<T: Sync> Sync for SharedGuard<'_, T> {}

impl<T> !Send for UniqueGuard<'_, T> {}
unsafe impl<T: Sync> Sync for UniqueGuard<'_, T> {}

/// Unique guard created by the methods [`RwLock::write`] and [`RwLock::try_write`].
/// 
/// Leaking this struct would cause deadlock with any further call to [`RwLock::write`] or [`RwLock::read`].
pub struct UniqueGuard<'a, T> {
    lock: &'a RwLock<T>,
}

impl<'a, T> Deref for UniqueGuard<'a, T> {
    type Target = T;

    #[inline]
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.lock.value.get() }
    }
}

impl<'a, T> DerefMut for UniqueGuard<'a, T> {
    #[inline]
    fn deref_mut(&mut self) -> &mut Self::Target {
        unsafe { &mut *self.lock.value.get() }
    }
}

impl<'a, T> Drop for UniqueGuard<'a, T> {
    #[inline]
    fn drop(&mut self) {
        if panicking() {
            self.lock.ref_count.fetch_or(POISON, SeqCst);
        }
        self.lock.ref_count.fetch_xor(WRITE, SeqCst);
        self.lock
            .local_ref_count.lock().unwrap().get_or_insert_with(ThreadLocal::new)
            .get_or(|| AtomicUsize::new(0))
            .fetch_xor(WRITE, Relaxed);
    }
}

impl<'a, T: Seek> Seek for UniqueGuard<'a, T> {
    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
        (**self).seek(pos)
    }
}

impl<'a, T: Write> Write for UniqueGuard<'a, T> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        (**self).write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        (**self).flush()
    }
}

impl<'a, T: Read> Read for UniqueGuard<'a, T> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        (**self).read(buf)
    }
}

impl<'a, T: BufRead> BufRead for UniqueGuard<'a, T> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        (**self).fill_buf()
    }

    fn consume(&mut self, amt: usize) {
        (**self).consume(amt)
    }
}

const LOCK: u8 = 2;
const POISON_M: u8 = 1;

/// An allocation-free [`Mutex`][`std::sync::Mutex`] made in pure Rust.
pub struct Mutex<T> {
    value: UnsafeCell<T>,
    ref_count: AtomicU8,
    // local ref_count used to detect deadlock whenever you try to acquire a lock that was blocked on the current thread on debug
    local_ref_count: non_thread_local::Mutex<Option<ThreadLocal<AtomicU8>>>,
}

unsafe impl<T: Send> Send for Mutex<T> {}
unsafe impl<T: Send> Sync for Mutex<T> {}

impl<T> Mutex<T> {
    /// Creates a new mutex in an unlocked state ready for use.
    #[inline]
    pub const fn new(x: T) -> Self {
        Self {
            value: UnsafeCell::new(x),
            ref_count: AtomicU8::new(0),
            local_ref_count: non_thread_local::Mutex::new(None),
        }
    }

    /// Acquires a mutex, blocking the current thread until it is able to do so.
    ///
    /// This function will block the local thread until it is available to acquire
    /// the mutex. Upon returning, the thread is the only thread with the lock
    /// held. An RAII guard is returned to allow scoped unlock of the lock. When
    /// the guard goes out of scope, the mutex will be unlocked.
    ///
    /// The exact behavior on locking a mutex in the thread which already holds
    /// the lock is left unspecified. However, this function will not return on
    /// the second call (it might panic or deadlock, for example).
    ///
    /// # Errors
    ///
    /// If another user of this mutex panicked while holding the mutex, then
    /// this call will return an error once the mutex is acquired.
    ///
    /// # Panics
    ///
    /// This function might panic when called if the lock is already held by
    /// the current thread only with `debug_assertions`.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::sync::Arc;
    /// use sync_2::Mutex;
    /// use std::thread;
    ///
    /// let mutex = Arc::new(Mutex::new(0));
    /// let c_mutex = mutex.clone();
    ///
    /// thread::spawn(move || {
    ///     *c_mutex.lock().unwrap() = 10;
    /// }).join().expect("thread::spawn failed");
    /// assert_eq!(*mutex.lock().unwrap(), 10);
    /// ```
    #[inline]
    pub fn lock(&self) -> LockResult<MutexGuard<'_, T>> {
        if self
            .local_ref_count.lock().unwrap().get_or_insert_with(ThreadLocal::new)
            .get_or(|| AtomicU8::new(0))
            .fetch_or(LOCK, Relaxed)
            == LOCK
        {
            panic!("mutex lock would result in deadlock")
        }

        loop {
            match self.try_lock() {
                Ok(e) => break Ok(e),
                Err(WouldBlock) => spin_loop(),
                Err(Poisoned(e)) => break Err(e),
            }
        }
    }

    /// Attempts to acquire this lock.
    ///
    /// If the lock could not be acquired at this time, then [`Err`] is returned.
    /// Otherwise, an RAII guard is returned. The lock will be unlocked when the
    /// guard is dropped.
    ///
    /// This function does not block.
    ///
    /// # Errors
    ///
    /// If another user of this mutex panicked while holding the mutex, then
    /// this call will return failure if the mutex would otherwise be
    /// acquired.
    ///
    /// [`Err`]: ../../std/result/enum.Result.html#variant.Err
    ///
    /// # Examples
    ///
    /// ```
    /// use std::sync::Arc;
    /// use sync_2::Mutex;
    /// use std::thread;
    ///
    /// let mutex = Arc::new(Mutex::new(0));
    /// let c_mutex = mutex.clone();
    ///
    /// thread::spawn(move || {
    ///     let mut lock = c_mutex.try_lock();
    ///     if let Ok(ref mut mutex) = lock {
    ///         **mutex = 10;
    ///     } else {
    ///         println!("try_lock failed");
    ///     }
    /// }).join().expect("thread::spawn failed");
    /// assert_eq!(*mutex.lock().unwrap(), 10);
    /// ```
    pub fn try_lock(&self) -> TryLockResult<MutexGuard<'_, T>> {
        let x = match self.ref_count.fetch_update(
            SeqCst,
            SeqCst,
            |x| if x < LOCK { Some(x | LOCK) } else { None },
        ) {
            Ok(x) => x,
            Err(_) => return Err(WouldBlock),
        };

        if x < POISON_M {
            Ok(MutexGuard { lock: self })
        } else {
            Err(Poisoned(PoisonError::new(MutexGuard { lock: self })))
        }
    }

    /// Determines whether the mutex is poisoned.
    ///
    /// If another thread is active, the mutex can still become poisoned at any
    /// time. You should not trust a `false` value for program correctness
    /// without additional synchronization.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::sync::Arc;
    /// use sync_2::Mutex;
    /// use std::thread;
    ///
    /// let mutex = Arc::new(Mutex::new(0));
    /// let c_mutex = mutex.clone();
    ///
    /// let _ = thread::spawn(move || {
    ///     let _lock = c_mutex.lock().unwrap();
    ///     panic!(); // the mutex gets poisoned
    /// }).join();
    /// assert_eq!(mutex.is_poisoned(), true);
    /// ```
    #[inline]
    pub fn is_poisoned(&self) -> bool {
        (self.ref_count.load(SeqCst) & POISON_M) == POISON_M
    }

    /// Returns a mutable reference to the underlying data.
    ///
    /// Since this call borrows the `Mutex` mutably, no actual locking needs to
    /// take place -- the mutable borrow statically guarantees no locks exist.
    ///
    /// # Errors
    ///
    /// If another user of this mutex panicked while holding the mutex, then
    /// this call will return an error instead.
    ///
    /// # Examples
    ///
    /// ```
    /// use sync_2::Mutex;
    ///
    /// let mut mutex = Mutex::new(0);
    /// *mutex.get_mut().unwrap() = 10;
    /// assert_eq!(*mutex.lock().unwrap(), 10);
    /// ```
    #[inline]
    pub fn get_mut(&mut self) -> LockResult<&mut T> {
        let x = unsafe { &mut *self.value.get() };

        if self.is_poisoned() {
            Err(PoisonError::new(x))
        } else {
            Ok(x)
        }
    }

    /// Consumes this mutex, returning the underlying data.
    ///
    /// # Errors
    ///
    /// If another user of this mutex panicked while holding the mutex, then
    /// this call will return an error instead.
    ///
    /// # Examples
    ///
    /// ```
    /// use sync_2::Mutex;
    ///
    /// let mutex = Mutex::new(0);
    /// assert_eq!(mutex.into_inner().unwrap(), 0);
    /// ```
    #[inline]
    pub fn into_inner(self) -> LockResult<T> {
        if self.is_poisoned() {
            Err(PoisonError::new(self.value.into_inner()))
        } else {
            Ok(self.value.into_inner())
        }
    }
}

impl<T> !Send for MutexGuard<'_, T> {}
unsafe impl<T: Sync> Sync for MutexGuard<'_, T> {}

/// Unique guard created by the method [`Mutex::lock`] and [`Mutex::try_lock`].
pub struct MutexGuard<'a, T> {
    lock: &'a Mutex<T>,
}

impl<'a, T> Deref for MutexGuard<'a, T> {
    type Target = T;

    #[inline]
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.lock.value.get() }
    }
}

impl<'a, T> DerefMut for MutexGuard<'a, T> {
    #[inline]
    fn deref_mut(&mut self) -> &mut Self::Target {
        unsafe { &mut *self.lock.value.get() }
    }
}

impl<'a, T> Drop for MutexGuard<'a, T> {
    #[inline]
    fn drop(&mut self) {
        if panicking() {
            self.lock.ref_count.fetch_or(POISON_M, SeqCst);
        }
        self.lock.ref_count.fetch_sub(LOCK, SeqCst);
        self.lock
            .local_ref_count.lock().unwrap().get_or_insert_with(ThreadLocal::new)
            .get_or(|| AtomicU8::new(0))
            .fetch_sub(LOCK, Relaxed);
    }
}

impl<'a, T: Seek> Seek for MutexGuard<'a, T> {
    #[inline]
    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
        (**self).seek(pos)
    }
}

impl<'a, T: Write> Write for MutexGuard<'a, T> {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        (**self).write(buf)
    }

    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        (**self).flush()
    }
}

impl<'a, T: Read> Read for MutexGuard<'a, T> {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        (**self).read(buf)
    }
}

impl<'a, T: BufRead> BufRead for MutexGuard<'a, T> {
    #[inline]
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        (**self).fill_buf()
    }

    #[inline]
    fn consume(&mut self, amt: usize) {
        (**self).consume(amt)
    }
}

impl<'a, T: AsRef<U>, U> AsRef<U> for MutexGuard<'a, T> {
    fn as_ref(&self) -> &U {
        (**self).as_ref()
    }
}

impl<'a, T: AsMut<U>, U> AsMut<U> for MutexGuard<'a, T> {
    fn as_mut(&mut self) -> &mut U {
        (**self).as_mut()
    }
}
}

#[cfg(not(debug_assertions))]
pub use non_thread_local::*;
#[cfg(debug_assertions)]
pub use thread_local_a::*;