Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/src/common/locked_ptr.h
14138 views
1
// SPDX-FileCopyrightText: 2019-2026 Connor McLaughlin <[email protected]>
2
// SPDX-License-Identifier: CC-BY-NC-ND-4.0
3
4
#pragma once
5
6
#include "types.h"
7
8
#include <mutex>
9
10
/// LockedPtr holds a pointer alongside a mutex, locking it on construction and
11
/// unlocking on destruction. The mutex type is templated, defaulting to std::mutex.
12
template<typename T, typename MutexType>
13
class LockedPtr
14
{
15
public:
16
ALWAYS_INLINE LockedPtr() = default;
17
18
ALWAYS_INLINE LockedPtr(MutexType& mutex, T* ptr) : m_ptr(ptr), m_mutex(&mutex) { m_mutex->lock(); }
19
20
ALWAYS_INLINE LockedPtr(MutexType& mutex, T* ptr, std::adopt_lock_t) : m_ptr(ptr), m_mutex(&mutex) {}
21
22
ALWAYS_INLINE LockedPtr(std::unique_lock<MutexType>&& lock, T* ptr) : m_ptr(ptr), m_mutex(lock.release()) {}
23
24
ALWAYS_INLINE ~LockedPtr()
25
{
26
if (m_mutex)
27
m_mutex->unlock();
28
}
29
30
ALWAYS_INLINE LockedPtr(LockedPtr&& other) : m_ptr(other.m_ptr), m_mutex(other.m_mutex)
31
{
32
other.m_ptr = nullptr;
33
other.m_mutex = nullptr;
34
}
35
36
LockedPtr(const LockedPtr&) = delete;
37
LockedPtr& operator=(const LockedPtr&) = delete;
38
39
ALWAYS_INLINE LockedPtr& operator=(LockedPtr&& other)
40
{
41
if (m_mutex)
42
m_mutex->unlock();
43
m_ptr = other.m_ptr;
44
m_mutex = other.m_mutex;
45
other.m_ptr = nullptr;
46
other.m_mutex = nullptr;
47
return *this;
48
}
49
50
ALWAYS_INLINE T& operator*() const { return *m_ptr; }
51
ALWAYS_INLINE T* operator->() const { return m_ptr; }
52
53
ALWAYS_INLINE explicit operator bool() const { return (m_ptr != nullptr); }
54
55
ALWAYS_INLINE T* get_ptr() const { return m_ptr; }
56
ALWAYS_INLINE MutexType* get_mutex() const { return m_mutex; }
57
58
private:
59
T* m_ptr = nullptr;
60
MutexType* m_mutex = nullptr;
61
};
62
63