From b99b79d8080cc1491f96069677d9ce0b7775a4f0 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 9 Sep 2026 23:02:20 +0200 Subject: chore: replace some naked pointers The coding guidelines explicitly prohibit the use of "naked"/C-style pointers. However, there were some prominent examples in the kapi and the core kernel source. This changeset replaces them with the appropriate smart pointer types. --- .../tb0003-facet-based-capability-dispatch.rst | 26 +++++++++++----------- docs/guides/device-drivers.rst | 6 ++--- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'docs') diff --git a/docs/briefs/tb0003-facet-based-capability-dispatch.rst b/docs/briefs/tb0003-facet-based-capability-dispatch.rst index 2cace2f3..70d183d0 100644 --- a/docs/briefs/tb0003-facet-based-capability-dispatch.rst +++ b/docs/briefs/tb0003-facet-based-capability-dispatch.rst @@ -76,12 +76,12 @@ Querying a Single Object struct device : kstd::enable_shared_from_this { - [[nodiscard]] auto facet(kapi::capabilities::facet_id id) noexcept -> void *; + [[nodiscard]] auto facet(kapi::capabilities::facet_id id) noexcept -> kstd::observer_ptr; template [[nodiscard]] auto facet() -> FacetType * { - return static_cast(facet(FacetType::id)); + return kstd::observer_ptr{static_cast(facet(FacetType::id).get())}; } template @@ -91,7 +91,7 @@ Querying a Single Object } protected: - auto virtual query_facet(kapi::capabilities::facet_id facet) -> void *; + auto virtual query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr; }; The base implementation of ``query_facet()`` simply returns ``nullptr``. @@ -106,15 +106,15 @@ A concrete device overrides it, checks the requested id against every facet it s [[nodiscard]] auto isa_name() const -> std::string_view override; protected: - auto query_facet(kapi::capabilities::facet_id facet) -> void * override; + auto query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr override; }; // arch/x86_64/arch/devices/pit.cpp - auto pit::query_facet(kapi::capabilities::facet_id facet) -> void * + auto pit::query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr { if (facet == arch::bus::isa_signature::id) { - return static_cast(this); + return kstd::make_observer(this); } return kapi::devices::device::query_facet(facet); // <-- the delegation } @@ -174,10 +174,10 @@ A device is not only queried for identification facets. ``bus`` itself answers t .. code-block:: cpp // kernel/kapi/devices/bus.cpp - auto bus::query_facet(kapi::capabilities::facet_id facet) -> void * + auto bus::query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr { - if (facet == bus::id) { return this; } - else if (facet == bus_protocol::id) { return m_protocol; } + if (facet == bus::id) { return kstd::observer_ptr{this}; } + else if (facet == bus_protocol::id) { return kstd::observer_ptr{m_protocol}; } return device::query_facet(facet); } @@ -209,7 +209,7 @@ Everything above answers "does *this specific* device or driver support facet X" auto withdraw(device const & device, kapi::capabilities::facet_id id) -> void; [[nodiscard]] auto all(kapi::capabilities::facet_id id) const -> kstd::vector; - [[nodiscard]] auto resolve(kapi::capabilities::facet_id id, std::string_view name) -> void *; + [[nodiscard]] auto resolve(kapi::capabilities::facet_id id, std::string_view name) -> kstd::observer_ptr; auto subscribe(kstd::weak_ptr observer) -> void; // ... @@ -281,11 +281,11 @@ The two device-model facets already shown (``isa_signature``/``isa_claim``, ``bl } protected: - auto query_facet(kapi::capabilities::facet_id facet) -> void * override + auto query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr override { if (facet == kapi::sensors::temperature_sensor::id) { - return static_cast(this); + return kstd::make_observer(this); } return kapi::devices::device::query_facet(facet); // never forget this line } @@ -344,7 +344,7 @@ Capability query without a language-provided RTTI mechanism is a solved problem, COM's ``IUnknown::QueryInterface`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -This is the closest real-world relative of facet dispatch, and almost certainly its distant conceptual ancestor. Every COM object implements ``HRESULT QueryInterface(REFIID riid, void ** ppvObject)``: given a 128-bit interface identifier (a GUID) rather than a string, it returns a pointer to that interface or an error [2]_. The shape is identical — an opaque object, a caller-supplied tag, an untyped-then-cast pointer back, no shared base class needed to know about every possible interface in advance. The differences are informative rather than superficial: COM's tags are GUIDs, generated to be globally, statistically unique, specifically to avoid the collision risk a string tag carries (see *Drawbacks*, below); ``QueryInterface`` is reference-counted (``AddRef``/``Release``) as part of the same call, because COM objects can be shared across process and apartment boundaries in ways a kernel device tree is not; and COM has a formal rule that interface identity, once shipped, can never change shape — a modified interface gets a new GUID rather than breaking existing implementers. TeachOS has no equivalent discipline yet (also noted below). +This is the closest real-world relative of facet dispatch, and almost certainly its distant conceptual ancestor. Every COM object implements ``HRESULT QueryInterface(REFIID riid, void * ppvObject)``: given a 128-bit interface identifier (a GUID) rather than a string, it returns a pointer to that interface or an error [2]_. The shape is identical — an opaque object, a caller-supplied tag, an untyped-then-cast pointer back, no shared base class needed to know about every possible interface in advance. The differences are informative rather than superficial: COM's tags are GUIDs, generated to be globally, statistically unique, specifically to avoid the collision risk a string tag carries (see *Drawbacks*, below); ``QueryInterface`` is reference-counted (``AddRef``/``Release``) as part of the same call, because COM objects can be shared across process and apartment boundaries in ways a kernel device tree is not; and COM has a formal rule that interface identity, once shipped, can never change shape — a modified interface gets a new GUID rather than breaking existing implementers. TeachOS has no equivalent discipline yet (also noted below). UEFI Protocols ~~~~~~~~~~~~~~~~ diff --git a/docs/guides/device-drivers.rst b/docs/guides/device-drivers.rst index 3d3da182..a4bfe433 100644 --- a/docs/guides/device-drivers.rst +++ b/docs/guides/device-drivers.rst @@ -143,14 +143,14 @@ TeachOS's simplest real bus, ``kernel::bus::pseudo`` (``kernel/kernel/bus/pseudo { explicit pseudo(kstd::string name); protected: - auto query_facet(kapi::capabilities::facet_id facet) -> void * override; + auto query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr override; private: pseudo_signature m_signature{*this}; }; - auto pseudo::query_facet(kapi::capabilities::facet_id facet) -> void * + auto pseudo::query_facet(kapi::capabilities::facet_id facet) -> kstd::observer_ptr { - if (facet == kernel::bus::pseudo_signature::id) { return &m_signature; } + if (facet == kernel::bus::pseudo_signature::id) { return kstd::observer_ptr{&m_signature}; } return device::query_facet(facet); } -- cgit v1.2.3