summaryrefslogtreecommitdiff
path: root/include/libcamera/base/mutex.h
blob: 52441c55287a873f7b08ab9094bebbb88d693e6b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
 * Copyright (C) 2021, Google Inc.
 *
 * mutex.h - Mutex classes with clang thread safety annotation
 */

#pragma once

#include <condition_variable>
#include <mutex>

#include <libcamera/base/private.h>

#include <libcamera/base/thread_annotations.h>

namespace libcamera {

/* \todo using Mutex = std::mutex if libc++ is used. */

#ifndef __DOXYGEN__

class LIBCAMERA_TSA_CAPABILITY("mutex") Mutex final
{
public:
	constexpr Mutex()
	{
	}

	void lock() LIBCAMERA_TSA_ACQUIRE()
	{
		mutex_.lock();
	}

	void unlock() LIBCAMERA_TSA_RELEASE()
	{
		mutex_.unlock();
	}

private:
	friend class MutexLocker;

	std::mutex mutex_;
};

class LIBCAMERA_TSA_SCOPED_CAPABILITY MutexLocker final
{
public:
	explicit MutexLocker(Mutex &mutex) LIBCAMERA_TSA_ACQUIRE(mutex)
		: lock_(mutex.mutex_)
	{
	}

	MutexLocker(Mutex &mutex, std::defer_lock_t t) noexcept LIBCAMERA_TSA_EXCLUDES(mutex)
		: lock_(mutex.mutex_, t)
	{
	}

	~MutexLocker() LIBCAMERA_TSA_RELEASE()
	{
	}

	void lock() LIBCAMERA_TSA_ACQUIRE()
	{
		lock_.lock();
	}

	bool try_lock() LIBCAMERA_TSA_TRY_ACQUIRE(true)
	{
		return lock_.try_lock();
	}

	void unlock() LIBCAMERA_TSA_RELEASE()
	{
		lock_.unlock();
	}

private:
	friend class ConditionVariable;

	std::unique_lock<std::mutex> lock_;
};

class ConditionVariable final
{
public:
	ConditionVariable()
	{
	}

	void notify_one() noexcept
	{
		cv_.notify_one();
	}

	void notify_all() noexcept
	{
		cv_.notify_all();
	}

	template<class Predicate>
	void wait(MutexLocker &locker, Predicate stopWaiting)
	{
		cv_.wait(locker.lock_, stopWaiting);
	}

	template<class Rep, class Period, class Predicate>
	bool wait_for(MutexLocker &locker,
		      const std::chrono::duration<Rep, Period> &relTime,
		      Predicate stopWaiting)
	{
		return cv_.wait_for(locker.lock_, relTime, stopWaiting);
	}

private:
	std::condition_variable cv_;
};

#else /* __DOXYGEN__ */

class Mutex final
{
};

class MutexLocker final
{
};

class ConditionVariable final
{
};

#endif /* __DOXYGEN__ */
} /* namespace libcamera */