aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-07-26 13:23:46 +0200
committerFelix Morgner <felix.morgner@ost.ch>2026-07-26 13:23:46 +0200
commit4cc05543d48a35908b0756e133bd668745bd95c3 (patch)
treee72c2f5e9e11120ca11837aa43caac47ef571af9
parent5a5fefba28a52feffadf2b810b2f935934aa7b0b (diff)
downloadkernel-4cc05543d48a35908b0756e133bd668745bd95c3.tar.xz
kernel-4cc05543d48a35908b0756e133bd668745bd95c3.zip
kapi: implement device removal
-rw-r--r--kapi/kapi/devices/device_registry.hpp30
-rw-r--r--kernel/kapi/devices/device_registry.cpp82
2 files changed, 106 insertions, 6 deletions
diff --git a/kapi/kapi/devices/device_registry.hpp b/kapi/kapi/devices/device_registry.hpp
index 3952db66..a65bd4ad 100644
--- a/kapi/kapi/devices/device_registry.hpp
+++ b/kapi/kapi/devices/device_registry.hpp
@@ -18,12 +18,36 @@ namespace kapi::devices
//! @addtogroup kapi-devices-kernel-defined
//! @{
+ //! The interface for types interested in being notified about changes in the device registry.
+ struct device_registry_observer
+ {
+ //! Enable correct destruction through base pointers.
+ virtual ~device_registry_observer() = default;
+
+ //! Called after a device has been added to the registry.
+ //!
+ //! @param device The device that was added.
+ virtual auto on_device_added(kstd::shared_ptr<device> const & device) -> void = 0;
+
+ //! Called after a device has been removed from the registry.
+ //!
+ //! @param device The device that was remove.
+ virtual auto on_device_removed(device & device) -> void = 0;
+ };
+
+ //! @}
+
+ //! @addtogroup kapi-devices-kernel-defined
+ //! @{
+
struct device_registry
{
device_registry() = default;
+ //! Initialize the global singleton registry instance.
auto static init() -> void;
+ //! Get the global singleton registry instance.
auto static get() -> device_registry &;
//! Add a new device to the kernel's device registry.
@@ -49,8 +73,14 @@ namespace kapi::devices
//! @return every device current reachable through the registry.
[[nodiscard]] auto all() const -> kstd::vector<kstd::shared_ptr<device>>;
+ //! Subscribe to device registry notifications.
+ //!
+ //! @param observer The observer to notify.
+ auto subscribe(kstd::weak_ptr<device_registry_observer> observer) -> void;
+
private:
kstd::flat_map<kstd::string, kstd::weak_ptr<device>> m_devices{};
+ kstd::vector<kstd::weak_ptr<device_registry_observer>> m_observers{};
};
//! @}
diff --git a/kernel/kapi/devices/device_registry.cpp b/kernel/kapi/devices/device_registry.cpp
index aca0e7fe..f5c20a6d 100644
--- a/kernel/kapi/devices/device_registry.cpp
+++ b/kernel/kapi/devices/device_registry.cpp
@@ -49,29 +49,89 @@ namespace kapi::devices
kstd::println("[OS:DEV] Registering device {}", device->name());
+ auto added = false;
+
+ // TODO: lock the registry
auto found = m_devices.find(device->name());
if (found != m_devices.end())
{
if (!found->second.expired())
{
- return false;
+ added = false;
}
found->second = device;
- return true;
+ added = true;
+ }
+ else
+ {
+ added = m_devices.emplace(device->name(), device).second;
+ }
+ // TODO: unlock registry
+
+ if (!added)
+ {
+ return false;
}
- return m_devices.emplace(device->name(), device).second;
+ // TODO: consider if we need to lock the registry observers here, since somebody may add an observer in the meantime
+ // once multiple codepaths can run at the same time.
+ for (auto const & observer : m_observers)
+ {
+ if (auto locked_observer = observer.lock())
+ {
+ locked_observer->on_device_added(device);
+ }
+ }
+
+ // TODO: lock registry
+ erase_if(m_observers, [](auto const & observer) { return observer.expired(); });
+ // TODO: unlock registry
+
+ return true;
}
- auto device_registry::remove(device &) -> bool
+ auto device_registry::remove(device & device) -> bool
{
- kstd::println("[OS:DEV] TODO: implement device deregistration");
- return false;
+ // TODO: lock registry
+
+ auto found = m_devices.find(device.name());
+ if (found == m_devices.end())
+ {
+ return false;
+ }
+
+ auto locked = found->second.lock();
+ if (!locked || locked.get() != &device)
+ {
+ return false;
+ }
+
+ found->second = kstd::weak_ptr<struct device>{};
+
+ // TODO: unlock registry
+
+ kstd::println("[OS:DEV] Unregistering device {}", device.name());
+
+ for (auto const & observer : m_observers)
+ {
+ if (auto locked_observer = observer.lock())
+ {
+ locked_observer->on_device_removed(device);
+ }
+ }
+
+ // TODO: lock registry
+ erase_if(m_observers, [](auto const & observer) { return observer.expired(); });
+ // TODO: unlock registry
+
+ return true;
}
auto device_registry::find(std::string_view name) const -> kstd::shared_ptr<device>
{
+ // TODO: lock registry
+
auto found = m_devices.find(kstd::string{name});
if (found == m_devices.end())
{
@@ -83,6 +143,8 @@ namespace kapi::devices
auto device_registry::all() const -> kstd::vector<kstd::shared_ptr<device>>
{
+ // TODO: lock registry
+
auto result = kstd::vector<kstd::shared_ptr<device>>{};
for (auto const & [name, weak_device] : m_devices)
@@ -95,6 +157,14 @@ namespace kapi::devices
return result;
}
+
+ auto device_registry::subscribe(kstd::weak_ptr<device_registry_observer> observer) -> void
+ {
+ // TODO: lock registry
+
+ erase_if(m_observers, [](auto const & observer) { return observer.expired(); });
+ m_observers.push_back(observer);
+ }
} // namespace kapi::devices
namespace kapi::test_support::devices