#pragma once /* * Copyright (c) 2016 MariaDB Corporation Ab * * Use of this software is governed by the Business Source License included * in the LICENSE.TXT file and at www.mariadb.com/bsl11. * * Change Date: 2020-01-01 * * On the date above, in accordance with the Business Source License, use * of this software will be governed by version 2 or later of the General * Public License. */ #include #include namespace maxscale { class SpinLockGuard; /** * @class SpinLock spinlock.hh * * The class SpinLock is a simple class that wraps a regular SPINLOCK * and provides equivalent functionality. */ class SpinLock { public: friend class SpinLockGuard; /** * Creates a spinlock. */ SpinLock() { spinlock_init(&m_lock); } ~SpinLock() { } /** * Acquires the spinlock. */ void acquire() const { spinlock_acquire(&m_lock); } /** * Releases the spinlock. */ void release() const { spinlock_release(&m_lock); } private: SpinLock(const SpinLock&) /* = delete */; SpinLock& operator = (const SpinLock&) /* = delete */; private: mutable SPINLOCK m_lock; }; /** * @class SpinLockGuard spinlock.hh * * The class SpinLockGuard is a spinlock wrapper that provides a RAII-style * mechanism for owning a spinlock for the duration of a scoped block. When * a SpinLockGuard object is created, it attempts to take ownership of the * spinlock it is given. When control leaves the scope in which the * SpinLockGuard object was created, the SpinLockGuard is destructed and the * mutex is released. */ class SpinLockGuard { public: /** * Creates the guard and locks the provided lock. * * @param lock The spinlock to lock. */ SpinLockGuard(const SPINLOCK& lock) : m_lock(lock) { spinlock_acquire(&m_lock); } /** * Creates the guard and locks the provided lock. * * @param lock The spinlock to lock. */ SpinLockGuard(const SpinLock& lock) : m_lock(lock.m_lock) { spinlock_acquire(&m_lock); } /** * Destroys the guard and unlocks the lock that was provided when * the guard was created. */ ~SpinLockGuard() { spinlock_release(&m_lock); } private: SpinLockGuard(const SpinLockGuard&) /* = delete */; SpinLockGuard& operator = (const SpinLockGuard&) /* = delete */; const SPINLOCK& m_lock; }; }