aboutsummaryrefslogtreecommitdiff
path: root/kernel/kapi/devices/facet_registry.cpp
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-07-26 21:46:37 +0200
committerFelix Morgner <felix.morgner@ost.ch>2026-07-26 21:46:37 +0200
commit4b28e4626e744ac9b779a680f8e9647014956dda (patch)
tree9b5203e083ed27091c70d60e3cdf9284af680c81 /kernel/kapi/devices/facet_registry.cpp
parente7cb0a5dab291d453fa34c5d1250d85e82478ecf (diff)
downloadkernel-4b28e4626e744ac9b779a680f8e9647014956dda.tar.xz
kernel-4b28e4626e744ac9b779a680f8e9647014956dda.zip
kapi/devices: implement locking discipline
Diffstat (limited to 'kernel/kapi/devices/facet_registry.cpp')
-rw-r--r--kernel/kapi/devices/facet_registry.cpp130
1 files changed, 81 insertions, 49 deletions
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 <kapi/test_support/devices.hpp>
#include <kstd/memory.hpp>
+#include <kstd/mutex.hpp>
#include <kstd/result.hpp>
#include <kstd/string.hpp>
#include <kstd/system_error.hpp>
@@ -46,64 +47,87 @@ namespace kapi::devices
auto facet_registry::do_publish(kstd::shared_ptr<device> device, kstd::string name, kapi::capabilities::facet_id id,
void * facet) -> kstd::result<void>
{
- // TODO: lock registry
+ auto published = std::optional<entry>{};
- 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<kstd::weak_ptr<facet_registry_observer>>{};
+ auto static_observers = kstd::vector<facet_registry_observer *>{};
+ {
+ 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<kstd::weak_ptr<facet_registry_observer>>{};
+ auto static_observers = kstd::vector<facet_registry_observer *>{};
+ {
+ 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<devices::device &>(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<devices::device &>(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<kapi::capabilities::facet_id>{};
- 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<entry>
{
- // 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<device>{};
+ {
+ 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<facet_registry_observer> 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);