/* * Copyright (c) 2021, the SerenityOS developers. * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #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(LockLocation const& location) const { return LockedShared(this, this->ContendedResource::m_mutex, location); } LockedExclusive lock_exclusive(LockLocation const& location) { return LockedExclusive(this, this->ContendedResource::m_mutex, location); } public: using T::T; ProtectedValue() = default; template decltype(auto) with_shared(Callback callback, LockLocation const& location = LockLocation::current()) const { auto lock = lock_shared(location); return callback(*lock); } template decltype(auto) with_exclusive(Callback callback, LockLocation const& location = LockLocation::current()) { auto lock = lock_exclusive(location); return callback(*lock); } template void for_each_shared(Callback callback, LockLocation const& location = LockLocation::current()) const { with_shared([&](const auto& value) { for (auto& item : value) callback(item); }, location); } template void for_each_exclusive(Callback callback, LockLocation const& location = LockLocation::current()) { with_exclusive([&](auto& value) { for (auto& item : value) callback(item); }, location); } }; }