6#if ORIGINAL_COMPILER_GCC || ORIGINAL_COMPILER_CLANG
8#elif ORIGINAL_COMPILER_MSVC
130 static constexpr auto MANUAL_LOCK = lockPolicy::MANUAL_LOCK;
132 static constexpr auto AUTO_LOCK = lockPolicy::AUTO_LOCK;
134 static constexpr auto TRY_LOCK = lockPolicy::TRY_LOCK;
136 static constexpr auto ADOPT_LOCK = lockPolicy::ADOPT_LOCK;
151#if ORIGINAL_COMPILER_GCC || ORIGINAL_COMPILER_CLANG
164 using native_handle = pthread_mutex_t;
173 pMutex(pMutex&&) =
delete;
176 pMutex& operator=(pMutex&&) =
delete;
182 [[nodiscard]] ul_integer id()
const override;
188 [[nodiscard]]
void* nativeHandle() noexcept override;
194 void lock() override;
201 bool tryLock() override;
207 void unlock() override;
215#elif ORIGINAL_COMPILER_MSVC
216 class wMutex final :
public mutexBase {
219 using native_handle = SRWLOCK;
223 wMutex(wMutex&&) =
delete;
225 wMutex& operator=(wMutex&&) =
delete;
227 [[nodiscard]] ul_integer id()
const override;
229 [[nodiscard]]
void* nativeHandle() noexcept override;
231 void lock() override;
233 bool tryLock() override;
235 void unlock() override;
242 #if ORIGINAL_COMPILER_GCC || ORIGINAL_COMPILER_CLANG
244 #elif ORIGINAL_COMPILER_MSVC
250 #if ORIGINAL_COMPILER_GCC || ORIGINAL_COMPILER_CLANG
251 pMutex::native_handle;
252 #elif ORIGINAL_COMPILER_MSVC
253 wMutex::native_handle;
264 [[
nodiscard]]
void* nativeHandle()
noexcept override;
266 void lock()
override;
268 bool tryLock()
override;
270 void unlock()
override;
385 [[
nodiscard]]
bool isLocked()
const noexcept override;
391 void lock()
override;
398 bool tryLock()
override;
404 void unlock()
override;
419#if ORIGINAL_COMPILER_GCC || ORIGINAL_COMPILER_CLANG
420inline original::pMutex::pMutex() : mutex_{} {
421 if (
const int code = pthread_mutex_init(&this->mutex_,
nullptr);
423 throw sysError(
"Failed to initialize mutex (pthread_mutex_init returned " +
printable::formatString(code) +
")");
428 return reinterpret_cast<ul_integer
>(&this->mutex_);
431inline void* original::pMutex::nativeHandle() noexcept
433 return &this->mutex_;
436inline void original::pMutex::lock() {
437 if (
const int code = pthread_mutex_lock(&this->mutex_);
443inline bool original::pMutex::tryLock() {
444 if (
const int code = pthread_mutex_trylock(&this->mutex_);
449 throw sysError(
"Failed to try-lock mutex (pthread_mutex_try-lock returned " +
printable::formatString(code) +
")");
454inline void original::pMutex::unlock() {
455 if (
const int code = pthread_mutex_unlock(&this->mutex_);
457 throw sysError(
"Failed to unlock mutex (pthread_mutex_unlock returned " +
printable::formatString(code) +
")");
461inline original::pMutex::~pMutex() {
462 if (
const int code = pthread_mutex_destroy(&this->mutex_);
464 std::cerr <<
"Fatal error: Failed to destroy mutex (pthread_mutex_destroy returned "
465 << code <<
")" << std::endl;
469#elif ORIGINAL_COMPILER_MSVC
470inline original::wMutex::wMutex()
472 InitializeSRWLock(&this->lock_);
477 return reinterpret_cast<ul_integer
>(&this->lock_);
480inline void* original::wMutex::nativeHandle() noexcept
485inline void original::wMutex::lock()
487 AcquireSRWLockExclusive(&this->lock_);
490inline bool original::wMutex::tryLock()
492 return TryAcquireSRWLockExclusive(&this->lock_) != 0;
495inline void original::wMutex::unlock()
497 ReleaseSRWLockExclusive(&this->lock_);
500inline original::wMutex::~wMutex() =
default;
504inline original::mutex::mutex() =
default;
508 return this->mutex_.id();
513 return this->mutex_.nativeHandle();
523 return this->mutex_.tryLock();
543 this->is_locked =
true;
548 return this->is_locked;
553 throw sysError(
"Cannot lock uniqueLock: already locked");
556 this->is_locked =
true;
561 throw sysError(
"Cannot try-lock uniqueLock: already locked");
563 this->is_locked = this->mutex_.tryLock();
564 return this->is_locked;
568 if (this->is_locked){
570 this->is_locked =
false;
578template<
typename...
MUTEX>
581 (..., this->m_list.template
get<IDXES>()->lock());
582 this->is_locked_all =
true;
585template<
typename... MUTEX>
589 bool lock_status[
sizeof...(IDXES)] = {};
590 auto tryLockStatusUpdate = [&](
auto i,
auto* mutex) {
591 if (mutex->tryLock()) {
592 lock_status[i] =
true;
599 ((tryLockStatusUpdate(idx++, this->m_list.template get<IDXES>())), ...);
604 ? this->m_list.template get<IDXES>()->unlock() : void(), ++idx), ...);
606 this->is_locked_all = success;
610template<
typename... MUTEX>
613 (..., this->m_list.template get<IDXES>()->unlock());
616template<
typename... MUTEX>
620template<
typename...
MUTEX>
633 this->is_locked_all =
true;
637template<
typename...
MUTEX>
639 return this->is_locked_all;
642template<
typename...
MUTEX>
644 if (this->is_locked_all)
645 throw sysError(
"Cannot lock multiLock: already locked");
650template<
typename...
MUTEX>
652 if (this->is_locked_all)
653 throw sysError(
"Cannot try-lock multiLock: already locked");
658template<
typename...
MUTEX>
660 if (this->is_locked_all)
664template<
typename...
MUTEX>
Abstract base class for lock guard implementations.
Definition mutex.h:91
static constexpr auto TRY_LOCK
Constant for try-lock policy.
Definition mutex.h:134
static constexpr auto AUTO_LOCK
Constant for automatic lock policy.
Definition mutex.h:132
lockPolicy
Locking policies for guard construction.
Definition mutex.h:122
lockGuard & operator=(const lockGuard &)=delete
Deleted copy assignment operator.
virtual bool tryLock()=0
Attempts to lock the associated mutex(es) without blocking.
virtual void unlock()=0
Unlocks the associated mutex(es)
virtual bool isLocked() const noexcept=0
Checks if the guard currently holds the lock.
lockGuard()=default
Default constructor.
static constexpr auto MANUAL_LOCK
Constant for manual lock policy.
Definition mutex.h:130
virtual void lock()=0
Locks the associated mutex(es)
virtual ~lockGuard()=default
Virtual destructor.
lockGuard(const lockGuard &)=delete
Deleted copy constructor.
static constexpr auto ADOPT_LOCK
Constant for adopt lock policy.
Definition mutex.h:136
RAII wrapper for multiple mutex locking.
Definition mutex.h:339
void unlock() override
Unlocks all managed mutexes.
Definition mutex.h:659
multiLock & operator=(multiLock &&)=delete
Deleted move assignment operator.
void lock() override
Locks all managed mutexes.
Definition mutex.h:643
bool tryLock() override
Attempts to lock all managed mutexes without blocking.
Definition mutex.h:651
multiLock(multiLock &&)=delete
Deleted move constructor.
multiLock(MUTEX &... mutex)
Constructs a multiLock with AUTO_LOCK policy.
Definition mutex.h:617
bool isLocked() const noexcept override
Checks if all mutexes are currently locked.
Definition mutex.h:638
~multiLock() override
Destructor - automatically unlocks all if locked.
Definition mutex.h:665
Abstract base class for mutex implementations.
Definition mutex.h:37
virtual void unlock()=0
Unlocks the mutex.
virtual void * nativeHandle() noexcept=0
Gets the native handle of the mutex.
mutexBase(const mutexBase &)=delete
Deleted copy constructor.
mutexBase & operator=(const mutexBase &)=delete
Deleted copy assignment operator.
virtual void lock()=0
Locks the mutex, blocking if necessary.
virtual bool tryLock()=0
Attempts to lock the mutex without blocking.
virtual ul_integer id() const =0
Gets a unique identifier for the mutex.
mutexBase()=default
Default constructor.
bool tryLock() override
Attempts to lock the mutex without blocking.
Definition mutex.h:521
ul_integer id() const override
Gets a unique identifier for the mutex.
Definition mutex.h:506
void unlock() override
Unlocks the mutex.
Definition mutex.h:526
void lock() override
Locks the mutex, blocking if necessary.
Definition mutex.h:516
void * nativeHandle() noexcept override
Gets the native handle of the mutex.
Definition mutex.h:511
Unique ownership smart pointer with move semantics.
Definition ownerPtr.h:37
TYPE * unlock()
Release ownership of managed object.
Definition ownerPtr.h:218
static std::string formatString(const TYPE &t)
Universal value-to-string conversion with type-specific formatting.
Definition printable.h:339
Exception for generic system failure.
Definition error.h:413
Container for multiple heterogeneous elements.
Definition tuple.h:57
RAII wrapper for single mutex locking.
Definition mutex.h:280
void unlock() override
Unlocks the associated mutex.
Definition mutex.h:567
uniqueLock & operator=(uniqueLock &&)=delete
Deleted move assignment operator.
void lock() override
Locks the associated mutex.
Definition mutex.h:551
uniqueLock(uniqueLock &&)=delete
Deleted move constructor.
bool isLocked() const noexcept override
Checks if the lock is currently held.
Definition mutex.h:547
uniqueLock(mutexBase &mutex, lockPolicy policy=AUTO_LOCK)
Constructs a uniqueLock with specified policy.
Definition mutex.h:531
bool tryLock() override
Attempts to lock the associated mutex without blocking.
Definition mutex.h:559
~uniqueLock() override
Destructor - automatically unlocks if locked.
Definition mutex.h:574
Platform-independent type definitions and compiler/platform detection.
Custom exception classes and callback validation utilities.
Main namespace for the project Original.
Definition algorithms.h:21
consteval auto makeSequence() noexcept
Creates an index sequence of given length.
Definition types.h:679
Heterogeneous tuple container implementation.
Time and date handling utilities.