#pragma once #include "abi/types.h" #include "abi/syscalls.h" #include "abi/ipc.h" #include "stddef.h" #include "stdint.h" namespace ipc { // Strongly typed result wrapper (no exceptions) template struct Result { sysret_t status; T value; constexpr bool is_ok() const noexcept { return status == SYS_OK; } constexpr bool is_err() const noexcept { return status != SYS_OK; } constexpr sysret_t error() const noexcept { return status; } }; struct FastResponse { uint64_t out0; uint64_t out1; }; struct IncomingRequest { uint64_t sender_tid; uint64_t opcode; uint64_t arg0; uint64_t arg1; }; // RAII Capability Handle class Capability { private: cap_t handle_; public: constexpr Capability() noexcept : handle_(CAP_NULL) {} constexpr explicit Capability(cap_t handle) noexcept : handle_(handle) {} ~Capability() { // Future: syscall to drop capability reference } Capability(const Capability&) = delete; Capability& operator=(const Capability&) = delete; constexpr Capability(Capability&& other) noexcept : handle_(other.handle_) { other.handle_ = CAP_NULL; } constexpr Capability& operator=(Capability&& other) noexcept { if (this != &other) { handle_ = other.handle_; other.handle_ = CAP_NULL; } return *this; } [[nodiscard]] constexpr cap_t get() const noexcept { return handle_; } [[nodiscard]] constexpr bool is_valid() const noexcept { return handle_ != CAP_NULL; } }; // RAII IPC Client Endpoint Wrapper class Endpoint { private: Capability cap_; public: explicit Endpoint(Capability&& cap) noexcept : cap_(static_cast(cap)) {} explicit Endpoint(cap_t cap) noexcept : cap_(cap) {} // Fast-path synchronous register call (zero allocations) [[nodiscard]] Result call( uint64_t opcode, uint64_t arg0 = 0, uint64_t arg1 = 0, uint64_t arg2 = 0, uint64_t arg3 = 0 ) const noexcept { uint64_t out0 = 0; uint64_t out1 = 0; sysret_t ret = sys_ipc_call_raw(cap_.get(), opcode, arg0, arg1, arg2, arg3, &out0, &out1); return Result{ .status = ret, .value = { out0, out1 } }; } [[nodiscard]] cap_t raw_handle() const noexcept { return cap_.get(); } }; // RAII IPC Server Endpoint Wrapper class ServerEndpoint { private: Capability cap_; public: explicit ServerEndpoint(Capability&& cap) noexcept : cap_(static_cast(cap)) {} explicit ServerEndpoint(cap_t cap) noexcept : cap_(cap) {} // Server main loop: Reply to previous sender and wait for next request [[nodiscard]] Result reply_and_recv( uint64_t reply_to_tid = 0, uint64_t reply_val0 = 0, uint64_t reply_val1 = 0 ) const noexcept { uint64_t sender_tid = 0; uint64_t opcode = 0; uint64_t arg0 = 0; uint64_t arg1 = 0; sysret_t ret = sys_ipc_reply_recv_raw(cap_.get(), reply_to_tid, reply_val0, reply_val1, &sender_tid, &opcode, &arg0, &arg1); return Result{ .status = ret, .value = { sender_tid, opcode, arg0, arg1 } }; } [[nodiscard]] cap_t raw_handle() const noexcept { return cap_.get(); } }; // RAII Shared Memory Buffer class SharedBuffer { private: Capability shm_cap_; void* base_addr_; size_t size_; public: SharedBuffer(Capability&& cap, void* addr, size_t sz) noexcept : shm_cap_(static_cast(cap)), base_addr_(addr), size_(sz) {} ~SharedBuffer() { // Future: sys_unmap(base_addr_, size_) } SharedBuffer(const SharedBuffer&) = delete; SharedBuffer& operator=(const SharedBuffer&) = delete; SharedBuffer(SharedBuffer&& other) noexcept : shm_cap_(static_cast(other.shm_cap_)), base_addr_(other.base_addr_), size_(other.size_) { other.base_addr_ = nullptr; other.size_ = 0; } [[nodiscard]] void* data() const noexcept { return base_addr_; } [[nodiscard]] size_t size() const noexcept { return size_; } [[nodiscard]] cap_t handle() const noexcept { return shm_cap_.get(); } }; } // namespace ipc