diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-07-24 10:35:34 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-07-24 10:35:34 +0200 |
| commit | eeffe2ad97710ec7265de5ab020989c5731059c9 (patch) | |
| tree | fa173631ea4fbcc017b92c29edd9b349577f54ce /kernel/kapi/devices | |
| parent | ef124ea26ebe98f16e0e8fb204ec1f419bf656ee (diff) | |
| download | kernel-eeffe2ad97710ec7265de5ab020989c5731059c9.tar.xz kernel-eeffe2ad97710ec7265de5ab020989c5731059c9.zip | |
kapi: generalize device interface resolution
Diffstat (limited to 'kernel/kapi/devices')
| -rw-r--r-- | kernel/kapi/devices/device.cpp | 15 | ||||
| -rw-r--r-- | kernel/kapi/devices/interface_registry.cpp | 23 | ||||
| -rw-r--r-- | kernel/kapi/devices/interface_registry.tests.cpp | 10 |
3 files changed, 37 insertions, 11 deletions
diff --git a/kernel/kapi/devices/device.cpp b/kernel/kapi/devices/device.cpp index 4c63f6a4..3eb9aaac 100644 --- a/kernel/kapi/devices/device.cpp +++ b/kernel/kapi/devices/device.cpp @@ -12,6 +12,21 @@ namespace kapi::devices : m_name(name) {} + auto device::as(interface interface) noexcept -> void * + { + return query_interface(interface); + } + + auto device::as(interface interface) const noexcept -> void const * + { + return const_cast<device *>(this)->query_interface(interface); + } + + auto device::is_a(interface interface) const noexcept -> bool + { + return const_cast<device *>(this)->query_interface(interface) != nullptr; + } + auto device::name() const -> kstd::string const & { return m_name; diff --git a/kernel/kapi/devices/interface_registry.cpp b/kernel/kapi/devices/interface_registry.cpp index d959c857..2ff42aa3 100644 --- a/kernel/kapi/devices/interface_registry.cpp +++ b/kernel/kapi/devices/interface_registry.cpp @@ -85,30 +85,41 @@ namespace kapi::devices return filtered; } - auto interface_registry::find(interface interface, std::string_view name) const -> kstd::result<entry> + auto interface_registry::resolve(interface interface, std::string_view name) -> void * { auto found = std::ranges::find_if( m_entries, [&](auto e) { return e.interface() == interface && e.name() == name && e.device(); }); + if (found == m_entries.cend()) { - return kstd::failure(make_error_code(kstd::errc::no_such_device)); + return nullptr; + } + else if (auto device = found->device()) + { + return resolve(interface, *device); } - return *found; + return nullptr; } - auto interface_registry::find(interface interface, device const & device) const -> kstd::result<entry> + auto interface_registry::resolve(interface interface, device & device) -> void * { + if (auto by_device = device.as(interface)) + { + return by_device; + } + auto found = std::ranges::find_if(m_entries, [&](auto e) { auto locked_device = e.device(); return e.interface() == interface && locked_device && locked_device.get() == &device; }); + if (found == m_entries.cend()) { - return kstd::failure(make_error_code(kstd::errc::no_such_device)); + return nullptr; } - return *found; + return found->implementation(); } } // namespace kapi::devices diff --git a/kernel/kapi/devices/interface_registry.tests.cpp b/kernel/kapi/devices/interface_registry.tests.cpp index 100954ea..f82e867e 100644 --- a/kernel/kapi/devices/interface_registry.tests.cpp +++ b/kernel/kapi/devices/interface_registry.tests.cpp @@ -133,23 +133,23 @@ SCENARIO("Publishing and finding a device", "[kapi][devices][interface_registry] THEN("find finds the published capability by name") { - REQUIRE(registry.find<probe_device>("probe0")); + REQUIRE(registry.resolve<probe_device>("probe0")); } THEN("find for an unpublished capability does not find a device") { - REQUIRE_FALSE(registry.find<const_device>("probe0")); + REQUIRE_FALSE(registry.resolve<const_device>("probe0")); } THEN("find for an unpublished device does not find a device") { - REQUIRE_FALSE(registry.find<probe_device>("probe1")); + REQUIRE_FALSE(registry.resolve<probe_device>("probe1")); } THEN("withdrawing an interface for a device removes it from the registry") { registry.unpublish(*device, probe_device::id); - REQUIRE_FALSE(registry.find<probe_device>("probe0")); + REQUIRE_FALSE(registry.resolve<probe_device>("probe0")); } } @@ -165,7 +165,7 @@ SCENARIO("Publishing and finding a device", "[kapi][devices][interface_registry] THEN("find() no longer finds it") { - REQUIRE_FALSE(registry.find<probe_device>("probe0")); + REQUIRE_FALSE(registry.resolve<probe_device>("probe0")); } } } |
