From 4b28e4626e744ac9b779a680f8e9647014956dda Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Sun, 26 Jul 2026 21:46:37 +0200 Subject: kapi/devices: implement locking discipline --- kernel/kapi/devices/facet_registry.cpp | 130 ++++++++++++++++++++------------- 1 file changed, 81 insertions(+), 49 deletions(-) (limited to 'kernel/kapi/devices/facet_registry.cpp') diff --git a/kernel/kapi/devices/facet_registry.cpp b/kernel/kapi/devices/facet_registry.cpp index 4aeebfc1..623ecba2 100644 --- a/kernel/kapi/devices/facet_registry.cpp +++ b/kernel/kapi/devices/facet_registry.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -46,64 +47,87 @@ namespace kapi::devices auto facet_registry::do_publish(kstd::shared_ptr device, kstd::string name, kapi::capabilities::facet_id id, void * facet) -> kstd::result { - // TODO: lock registry + auto published = std::optional{}; - erase_if(m_entries, [id](auto e) { return e.id() == id && !e.device(); }); - - if (!device || !facet || name.empty()) { - return kstd::failure(make_error_code(kstd::errc::invalid_argument)); - } + auto guard = kstd::lock_guard{m_lock}; - auto already_published = std::ranges::any_of( - m_entries, [&](auto const & entry) { return entry.id() == id && entry.device().get() == device.get(); }); + erase_if(m_entries, [id](auto e) { return e.id() == id && !e.device(); }); - if (already_published) - { - return kstd::failure(make_error_code(kstd::errc::file_exists)); - } + if (!device || !facet || name.empty()) + { + return kstd::failure(make_error_code(kstd::errc::invalid_argument)); + } - auto & published = m_entries.emplace_back(device, std::move(name), id, facet); + auto already_published = std::ranges::any_of( + m_entries, [&](auto const & entry) { return entry.id() == id && entry.device().get() == device.get(); }); - do_notify_published(id, published); + if (already_published) + { + return kstd::failure(make_error_code(kstd::errc::file_exists)); + } + + published = m_entries.emplace_back(device, std::move(name), id, facet); + } + + do_notify_published(id, *published); return kstd::success(); } auto facet_registry::do_notify_published(kapi::capabilities::facet_id id, entry const & published) -> void { - std::ranges::for_each(m_observers, [&](auto observer) { + auto observers = kstd::vector>{}; + auto static_observers = kstd::vector{}; + { + auto guard = kstd::lock_guard{m_lock}; + observers = m_observers; + static_observers = m_static_observers; + } + + std::ranges::for_each(observers, [&](auto observer) { if (auto locked_observer = observer.lock()) { locked_observer->on_facet_published(id, published); } }); - std::ranges::for_each(m_static_observers, [&](auto observer) { observer->on_facet_published(id, published); }); + std::ranges::for_each(static_observers, [&](auto observer) { observer->on_facet_published(id, published); }); } auto facet_registry::do_notify_withdrawn(kapi::capabilities::facet_id id, device const & device) -> void { - std::ranges::for_each(m_observers, [&](auto observer) { + auto observers = kstd::vector>{}; + auto static_observers = kstd::vector{}; + { + auto guard = kstd::lock_guard{m_lock}; + observers = m_observers; + static_observers = m_static_observers; + } + + std::ranges::for_each(observers, [&](auto observer) { if (auto locked_observer = observer.lock()) { locked_observer->on_facet_withdrawn(id, const_cast(device)); } }); - std::ranges::for_each(m_static_observers, [&](auto observer) { + std::ranges::for_each(static_observers, [&](auto observer) { observer->on_facet_withdrawn(id, const_cast(device)); }); } auto facet_registry::withdraw(device const & device, kapi::capabilities::facet_id id) -> void { - // TODO: lock registry + auto did_remove = false; - auto did_remove = erase_if(m_entries, [&](auto e) { - auto locked_device = e.device(); - return e.id() == id && locked_device && locked_device.get() == &device; - }) != 0; + { + auto guard = kstd::lock_guard{m_lock}; + did_remove = erase_if(m_entries, [&](auto e) { + auto locked_device = e.device(); + return e.id() == id && locked_device && locked_device.get() == &device; + }) != 0; + } if (did_remove) { @@ -113,26 +137,28 @@ namespace kapi::devices auto facet_registry::withdraw_all_for(device const & device) -> void { - // TODO: lock registry - auto withdrawn_facets = kstd::vector{}; - erase_if(m_entries, [&](auto e) { - auto locked_device = e.device(); - auto do_erase = locked_device && locked_device.get() == &device; - if (do_erase) - { - withdrawn_facets.push_back(e.id()); - } - return do_erase; - }); + { + auto guard = kstd::lock_guard{m_lock}; + + erase_if(m_entries, [&](auto e) { + auto locked_device = e.device(); + auto do_erase = locked_device && locked_device.get() == &device; + if (do_erase) + { + withdrawn_facets.push_back(e.id()); + } + return do_erase; + }); + } std::ranges::for_each(withdrawn_facets, [&](auto facet) { do_notify_withdrawn(facet, device); }); } auto facet_registry::all(kapi::capabilities::facet_id id) const -> kstd::vector { - // TODO: lock registry + auto guard = kstd::lock_guard{m_lock}; auto filtered = m_entries; erase_if(filtered, [&](auto e) { @@ -142,33 +168,39 @@ namespace kapi::devices return filtered; } - auto facet_registry::resolve(kapi::capabilities::facet_id id, std::string_view name) -> void * + auto facet_registry::resolve(kapi::capabilities::facet_id facet, std::string_view name) -> void * { - // TODO: lock registry + auto found_device = kstd::shared_ptr{}; + { + auto guard = kstd::lock_guard{m_lock}; - auto found = std::ranges::find_if(m_entries, [&](auto e) { return e.name() == name && e.device(); }); + auto found = std::ranges::find_if(m_entries, [&](auto e) { return e.name() == name && e.device(); }); - if (found == m_entries.cend()) - { - return nullptr; + if (found == m_entries.cend()) + { + return nullptr; + } + + found_device = found->device(); } - else if (auto device = found->device()) + + if (!found_device) { - return resolve(id, *device); + return nullptr; } - return nullptr; + return resolve(facet, *found_device); } auto facet_registry::resolve(kapi::capabilities::facet_id id, device & device) -> void * { - // TODO: lock registry - if (auto by_device = device.facet(id)) { return by_device; } + auto guard = kstd::lock_guard{m_lock}; + auto found = std::ranges::find_if(m_entries, [&](auto e) { auto locked_device = e.device(); return e.id() == id && locked_device && locked_device.get() == &device; @@ -184,7 +216,7 @@ namespace kapi::devices auto facet_registry::subscribe(kstd::weak_ptr observer) -> void { - // TODO: lock registry + auto guard = kstd::lock_guard{m_lock}; erase_if(m_observers, [](auto const & observer) { return observer.expired(); }); m_observers.push_back(observer); @@ -192,14 +224,14 @@ namespace kapi::devices auto facet_registry::subscribe(facet_registry_observer & observer) -> void { - // TODO: lock registry + auto guard = kstd::lock_guard{m_lock}; m_static_observers.push_back(&observer); } auto facet_registry::unsubscribe(facet_registry_observer & observer) -> void { - // TODO: lock registry + auto guard = kstd::lock_guard{m_lock}; erase_if(m_observers, [&](auto const & subscribed) { return subscribed.lock().get() == &observer; }); erase(m_static_observers, &observer); -- cgit v1.2.3