/** * @file IPC.cpp * @author apio (cloudapio.eu) * @brief Inter-process communication primitives. * * @copyright Copyright (c) 2023, the Luna authors. * */ #include namespace os::IPC { Result> ClientConnection::adopt_connection(LocalServer::Client&& connection) { return adopt_owned_if_nonnull(new (std::nothrow) ClientConnection(move(connection))); } ClientConnection::ClientConnection(LocalServer::Client&& connection) : m_connection(move(connection)) { } Result ClientConnection::check_for_messages() { if (m_ipc_in_progress) { m_ipc_in_progress = false; m_message_handler(*this, m_ipc_saved_id, m_arg); return {}; } u8 id; auto rc = m_connection.recv_typed(id); if (rc.has_error()) { if (rc.error() == EAGAIN) return {}; // No messages, and the caller does not want us to block. if (rc.error() == EINTR) return {}; // Let the caller check for anything having happened because a signal handler ran. return rc.release_error(); } m_message_handler(*this, id, m_arg); return {}; } Result ClientConnection::send_error(int error) { u8 id = 0; TRY(m_connection.send_typed(id)); TRY(m_connection.send_typed(error)); return {}; } Result> Client::connect(StringView path, bool blocking) { auto connection = TRY(LocalClient::connect(path, blocking)); return adopt_owned_if_nonnull(new (std::nothrow) Client(move(connection))); } Result Client::check_for_messages() { if (m_ipc_in_progress) { m_ipc_in_progress = false; m_message_handler(*this, m_ipc_saved_id, m_arg); return {}; } u8 id; auto rc = m_connection->recv_typed(id); if (rc.has_error()) { if (rc.error() == EAGAIN) return {}; // No messages, and the caller does not want us to block. if (rc.error() == EINTR) return {}; // Let the caller check for anything having happened because a signal handler ran. return rc.release_error(); } m_message_handler(*this, id, m_arg); return {}; } Client::Client(OwnedPtr&& connection) : m_connection(move(connection)) { } }