/* * Copyright (c) 2021, the SerenityOS developers. * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include namespace Kernel { template class SpinLockProtectedValue : private T , public SpinLockContendedResource { AK_MAKE_NONCOPYABLE(SpinLockProtectedValue); AK_MAKE_NONMOVABLE(SpinLockProtectedValue); protected: using LockedConst = SpinLockLockedResource; using LockedMutable = SpinLockLockedResource; LockedConst lock_const() const { return LockedConst(static_cast(this), this->SpinLockContendedResource::m_spinlock); } LockedMutable lock_mutable() { return LockedMutable(static_cast(this), this->SpinLockContendedResource::m_spinlock); } public: using T::T; SpinLockProtectedValue() = default; template decltype(auto) with(Callback callback) const { auto lock = lock_const(); return callback(*lock); } template decltype(auto) with(Callback callback) { auto lock = lock_mutable(); return callback(*lock); } template void for_each_const(Callback callback) const { with([&](const auto& value) { for (auto& item : value) callback(item); }); } template void for_each(Callback callback) { with([&](auto& value) { for (auto& item : value) callback(item); }); } }; }