flatten 20260225
This commit is contained in:
17
tjp/core/threads/std/Lock.h
Executable file
17
tjp/core/threads/std/Lock.h
Executable file
@@ -0,0 +1,17 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
struct RecursiveMutex;
|
||||
struct Mutex;
|
||||
struct SharedMutex;
|
||||
struct Event;
|
||||
|
||||
struct EmptyLock;
|
||||
struct EmptyMutex;
|
||||
|
||||
} // namespace
|
||||
227
tjp/core/threads/std/Lock.hpp
Executable file
227
tjp/core/threads/std/Lock.hpp
Executable file
@@ -0,0 +1,227 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
#include "../../assert/debug_assert.h"
|
||||
#include <vector>
|
||||
|
||||
#include "../LockedBy.hpp"
|
||||
|
||||
#include "../SharedLockGuard.hpp"
|
||||
#include "../UnlockGuard.hpp"
|
||||
#include "../TryLockGuard.hpp"
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
struct RecursiveMutex : LockedBy<std::recursive_mutex>
|
||||
{
|
||||
typedef std::lock_guard<RecursiveMutex> Lock;
|
||||
typedef TryLockGuard<RecursiveMutex> TryLock;
|
||||
} ;
|
||||
|
||||
struct Mutex : LockedBy<std::mutex>
|
||||
{
|
||||
typedef LockedBy<std::mutex> Super;
|
||||
typedef std::lock_guard<Mutex> Lock;
|
||||
typedef UnlockGuard<Mutex> Unlock;
|
||||
typedef TryLockGuard<Mutex> TryLock;
|
||||
|
||||
void lock ()
|
||||
{
|
||||
debug_assert(!locked_by_caller());
|
||||
Super::lock();
|
||||
}
|
||||
|
||||
auto try_lock()
|
||||
{
|
||||
return Super::try_lock();
|
||||
}
|
||||
|
||||
void unlock ()
|
||||
{
|
||||
Super::unlock();
|
||||
}
|
||||
} ;
|
||||
|
||||
struct SharedMutex : LockedBy<std::shared_mutex>
|
||||
{
|
||||
typedef LockedBy<std::shared_mutex> Super;
|
||||
typedef std::lock_guard<SharedMutex> Lock;
|
||||
typedef SharedLockGuard<SharedMutex> SharedLock;
|
||||
typedef TryLockGuard<SharedMutex> TryLock;
|
||||
|
||||
void lock ()
|
||||
{
|
||||
debug_assert(!locked_by_caller());
|
||||
Super::lock();
|
||||
}
|
||||
|
||||
auto try_lock()
|
||||
{
|
||||
return Super::try_lock();
|
||||
}
|
||||
|
||||
std::mutex shared_locks_mutex;
|
||||
std::vector<std::thread::id> shared_locks;
|
||||
|
||||
void lock_shared ()
|
||||
{
|
||||
m.lock_shared();
|
||||
|
||||
std::lock_guard l(shared_locks_mutex);
|
||||
shared_locks.push_back(std::this_thread::get_id());
|
||||
}
|
||||
|
||||
void unlock_shared ()
|
||||
{
|
||||
m.unlock_shared();
|
||||
|
||||
auto id = std::this_thread::get_id();
|
||||
|
||||
std::lock_guard l(shared_locks_mutex);
|
||||
for (auto &id_ : shared_locks)
|
||||
{
|
||||
if (id_ == id)
|
||||
{
|
||||
id_ = shared_locks.back();
|
||||
shared_locks.pop_back();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool shared_locked_by_caller()
|
||||
{
|
||||
auto id = std::this_thread::get_id();
|
||||
{
|
||||
std::lock_guard l(shared_locks_mutex);
|
||||
for (auto &id_ : shared_locks)
|
||||
if (id_ == id)
|
||||
return true;
|
||||
}
|
||||
|
||||
return locked_by_caller();
|
||||
}
|
||||
} ;
|
||||
|
||||
#else
|
||||
|
||||
struct RecursiveMutex : std::recursive_mutex
|
||||
{
|
||||
typedef std::lock_guard<RecursiveMutex> Lock;
|
||||
typedef UnlockGuard<RecursiveMutex> Unlock;
|
||||
using TryLock = TryLockGuard<RecursiveMutex>;
|
||||
} ;
|
||||
|
||||
struct Mutex : std::mutex {
|
||||
typedef std::lock_guard<Mutex> Lock;
|
||||
typedef UnlockGuard<Mutex> Unlock;
|
||||
using TryLock = TryLockGuard<Mutex>;
|
||||
} ;
|
||||
|
||||
struct SharedMutex : std::shared_mutex
|
||||
{
|
||||
typedef std::lock_guard<SharedMutex> Lock;
|
||||
typedef SharedLockGuard<SharedMutex> SharedLock;
|
||||
using TryLock = TryLockGuard<SharedMutex>;
|
||||
} ;
|
||||
|
||||
#endif
|
||||
|
||||
struct Event : std::condition_variable_any
|
||||
{
|
||||
struct Mutex : core::Mutex {
|
||||
using Lock = std::unique_lock<Mutex>;
|
||||
using TryLock = TryLockGuard<Mutex>;
|
||||
} ;
|
||||
} ;
|
||||
|
||||
struct EmptyMutex
|
||||
{
|
||||
struct Lock {};
|
||||
struct TryLock { operator bool() { return true; }};
|
||||
};
|
||||
|
||||
inline
|
||||
auto lock_of(RecursiveMutex &m)
|
||||
{
|
||||
return RecursiveMutex::Lock(m);
|
||||
}
|
||||
|
||||
inline
|
||||
auto lock_of(Mutex &m)
|
||||
{
|
||||
return Mutex::Lock(m);
|
||||
}
|
||||
|
||||
inline
|
||||
auto unlock_of(Mutex &m)
|
||||
{
|
||||
return Mutex::Unlock(m);
|
||||
}
|
||||
|
||||
inline
|
||||
auto unique_lock_of(Mutex &m)
|
||||
{
|
||||
return std::unique_lock(m);
|
||||
}
|
||||
|
||||
inline
|
||||
auto try_lock_of(Mutex &m)
|
||||
{
|
||||
return Mutex::TryLock(m);
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
auto lock_of(Event::Mutex &m)
|
||||
{
|
||||
return Event::Mutex::Lock(m);
|
||||
}
|
||||
|
||||
inline
|
||||
auto try_lock_of(Event::Mutex &m)
|
||||
{
|
||||
return Event::Mutex::TryLock(m);
|
||||
}
|
||||
|
||||
inline
|
||||
auto lock_of(SharedMutex &m)
|
||||
{
|
||||
return SharedMutex::Lock(m);
|
||||
}
|
||||
|
||||
inline
|
||||
auto try_lock_of(SharedMutex &m)
|
||||
{
|
||||
return SharedMutex::TryLock(m);
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
auto lock_of(EmptyMutex &m)
|
||||
{
|
||||
return EmptyMutex::Lock{};
|
||||
}
|
||||
|
||||
inline
|
||||
auto try_lock_of(EmptyMutex &m)
|
||||
{
|
||||
return EmptyMutex::TryLock{};
|
||||
}
|
||||
|
||||
inline
|
||||
SharedLockGuard<SharedMutex> shared_lock_of(SharedMutex &m_)
|
||||
{
|
||||
return SharedMutex::SharedLock(m_);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
Reference in New Issue
Block a user