diff --git a/Kernel/Locking/ProtectedValue.h b/Kernel/Locking/ProtectedValue.h new file mode 100644 index 0000000000..676f932473 --- /dev/null +++ b/Kernel/Locking/ProtectedValue.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace Kernel { + +template +class ProtectedValue : private T + , public ContendedResource { + AK_MAKE_NONCOPYABLE(ProtectedValue); + AK_MAKE_NONMOVABLE(ProtectedValue); + +protected: + using LockedShared = LockedResource; + using LockedExclusive = LockedResource; + + LockedShared lock_shared() const { return LockedShared(this, this->ContendedResource::m_mutex); } + LockedExclusive lock_exclusive() { return LockedExclusive(this, this->ContendedResource::m_mutex); } + +public: + using T::T; + + ProtectedValue() = default; + + template + decltype(auto) with_shared(Callback callback) const + { + auto lock = lock_shared(); + return callback(*lock); + } + + template + decltype(auto) with_exclusive(Callback callback) + { + auto lock = lock_exclusive(); + return callback(*lock); + } + + template + void for_each_shared(Callback callback) const + { + with_shared([&](const auto& value) { + for (auto& item : value) + callback(item); + }); + } + + template + void for_each_exclusive(Callback callback) + { + with_exclusive([&](auto& value) { + for (auto& item : value) + callback(item); + }); + } +}; + +}