mirror of
https://gitlab.com/Mr_Goldberg/goldberg_emulator
synced 2025-07-07 06:52:15 +08:00
Update Nemirtingas overlay to latest.
This commit is contained in:
96
overlay_experimental/System/ScopedLock.hpp
Normal file
96
overlay_experimental/System/ScopedLock.hpp
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) Nemirtingas
|
||||
* This file is part of System.
|
||||
*
|
||||
* System is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* System is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with System; if not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
#include <mutex>
|
||||
|
||||
namespace System {
|
||||
|
||||
class scoped_lock {
|
||||
struct value_holder
|
||||
{
|
||||
virtual ~value_holder() noexcept {}
|
||||
};
|
||||
|
||||
template<typename... Args>
|
||||
struct templated_value_holder : value_holder
|
||||
{
|
||||
template<std::size_t I = 0, typename... Tp>
|
||||
inline typename std::enable_if<I == sizeof...(Tp), void>::type unlock(std::tuple<Tp...>& t) { }
|
||||
|
||||
template<std::size_t I = 0, typename... Tp>
|
||||
inline typename std::enable_if<I < sizeof...(Tp), void>::type unlock(std::tuple<Tp...>& t)
|
||||
{
|
||||
std::get<I>(t).unlock();
|
||||
unlock<I + 1, Tp...>(t);
|
||||
}
|
||||
|
||||
explicit templated_value_holder(Args&... mutexes) : _mutexes(mutexes...) { std::lock(mutexes...); }
|
||||
explicit templated_value_holder(std::adopt_lock_t, Args&... mutexes) : _mutexes(mutexes...) {} // construct but don't lock
|
||||
|
||||
virtual ~templated_value_holder() noexcept { unlock(_mutexes); }
|
||||
|
||||
std::tuple<Args&...> _mutexes;
|
||||
};
|
||||
|
||||
template<typename Arg>
|
||||
struct templated_value_holder<Arg> : value_holder
|
||||
{
|
||||
explicit templated_value_holder(Arg& mutex) : _mutex(mutex) { _mutex.lock(); }
|
||||
explicit templated_value_holder(std::adopt_lock_t, Arg& mutex) : _mutex(mutex) {} // construct but don't lock
|
||||
|
||||
virtual ~templated_value_holder() noexcept { _mutex.unlock(); }
|
||||
|
||||
Arg& _mutex;
|
||||
};
|
||||
|
||||
value_holder* _val;
|
||||
|
||||
public:
|
||||
template<typename... Args>
|
||||
explicit scoped_lock(Args&... mutexes) : _val(new templated_value_holder<Args&...>(mutexes...)) { }
|
||||
|
||||
template<typename... Args>
|
||||
explicit scoped_lock(std::adopt_lock_t, Args&... mutexes) : _val(new templated_value_holder<Args&...>(std::adopt_lock, mutexes...)) { }
|
||||
|
||||
explicit scoped_lock(scoped_lock && other):
|
||||
_val(other._val)
|
||||
{
|
||||
other._val = nullptr;
|
||||
}
|
||||
|
||||
scoped_lock() noexcept:
|
||||
_val(nullptr)
|
||||
{}
|
||||
~scoped_lock() noexcept { delete _val; }
|
||||
|
||||
scoped_lock& operator=(scoped_lock && other)
|
||||
{
|
||||
_val = other._val;
|
||||
other._val = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
scoped_lock(const scoped_lock&) = delete;
|
||||
scoped_lock& operator=(const scoped_lock&) = delete;
|
||||
};
|
||||
|
||||
}
|
Reference in New Issue
Block a user