#pragma once /// \file kobject.h /// Definition of base type for user-interactable kernel objects #include "j6/errors.h" #include "j6/signals.h" #include "j6/types.h" #include "kutil/vector.h" class thread; /// Base type for all user-interactable kernel objects class kobject { public: /// Types of kernel objects. enum class type : uint16_t { none, event, channel, endpoint, vma, job, process, thread, }; kobject(type t, j6_signal_t signals = 0ull); virtual ~kobject(); /// Generate a new koid for a given type /// \arg t The object type /// \returns A new unique koid static j6_koid_t koid_generate(type t); /// Get the kobject type from a given koid /// \arg koid An existing koid /// \returns The object type for the koid static type koid_type(j6_koid_t koid); /// Get this object's type inline type get_type() const { return koid_type(m_koid); } /// Get this object's koid inline j6_koid_t koid() const { return m_koid; } /// Set the given signals active on this object /// \arg s The set of signals to assert void assert_signal(j6_signal_t s); /// Clear the given signals on this object /// \arg s The set of signals to deassert void deassert_signal(j6_signal_t s); /// Check if the given signals are set on this object /// \arg s The set of signals to check inline bool check_signal(j6_signal_t s) const { return (m_signals & s) == s; } /// Get the current object signal state inline j6_signal_t signals() const { return m_signals; } /// Increment the handle refcount inline void handle_retain() { ++m_handle_count; } /// Decrement the handle refcount inline void handle_release() { if (--m_handle_count == 0) on_no_handles(); } /// Add the given thread to the list of threads waiting on this object. inline void add_blocked_thread(thread *t) { m_blocked_threads.append(t); } /// Remove the given thread from the list of threads waiting on this object. inline void remove_blocked_thread(thread *t) { m_blocked_threads.remove_swap(t); } /// Perform any cleanup actions necessary to mark this object closed virtual void close(); /// Check if this object has been closed inline bool closed() const { return check_signal(j6_signal_closed); } protected: /// Interface for subclasses to handle when all handles are closed. Subclasses /// should either call the base version, or assert j6_signal_no_handles. virtual void on_no_handles(); private: kobject() = delete; kobject(const kobject &other) = delete; kobject(const kobject &&other) = delete; /// Notifiy observers of this object /// \arg result The result to pass to the observers void notify_signal_observers(); j6_koid_t m_koid; j6_signal_t m_signals; uint16_t m_handle_count; protected: kutil::vector m_blocked_threads; };