Serenity Operating System
1/*
2 * Copyright (c) 2022, kleines Filmröllchen <malu.bertsch@gmail.com>.
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#pragma once
8
9#include <AK/Concepts.h>
10#include <AK/Noncopyable.h>
11#include <LibThreading/Mutex.h>
12
13namespace Threading {
14
15template<typename T>
16class MutexProtected {
17 AK_MAKE_NONCOPYABLE(MutexProtected);
18 AK_MAKE_NONMOVABLE(MutexProtected);
19 using ProtectedType = T;
20
21public:
22 ALWAYS_INLINE MutexProtected() = default;
23 ALWAYS_INLINE MutexProtected(T&& value)
24 : m_value(move(value))
25 {
26 }
27 ALWAYS_INLINE explicit MutexProtected(T& value)
28 : m_value(value)
29 {
30 }
31
32 template<typename Callback>
33 decltype(auto) with_locked(Callback callback)
34 {
35 auto lock = this->lock();
36 // This allows users to get a copy, but if we don't allow references through &m_value, it's even more complex.
37 return callback(m_value);
38 }
39
40 template<VoidFunction<T> Callback>
41 void for_each_locked(Callback callback)
42 {
43 with_locked([&](auto& value) {
44 for (auto& item : value)
45 callback(item);
46 });
47 }
48
49private:
50 [[nodiscard]] ALWAYS_INLINE MutexLocker lock() { return MutexLocker(m_lock); }
51
52 T m_value;
53 Mutex m_lock {};
54};
55
56}