/* * 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); }); } }; }