Luna/libos/src/IPC.cpp

88 lines
2.4 KiB
C++
Raw Normal View History

2023-08-14 16:14:35 +00:00
/**
* @file IPC.cpp
* @author apio (cloudapio.eu)
* @brief Inter-process communication primitives.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#include <os/IPC.h>
namespace os::IPC
{
Result<OwnedPtr<ClientConnection>> ClientConnection::adopt_connection(LocalServer::Client&& connection)
2023-08-14 16:14:35 +00:00
{
return adopt_owned_if_nonnull(new (std::nothrow) ClientConnection(move(connection)));
}
ClientConnection::ClientConnection(LocalServer::Client&& connection) : m_connection(move(connection))
{
}
Result<void> 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 {};
}
2023-08-14 16:14:35 +00:00
u8 id;
auto rc = m_connection.recv_typed(id);
2023-08-14 16:14:35 +00:00
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.
2023-08-14 16:14:35 +00:00
return rc.release_error();
}
m_message_handler(*this, id, m_arg);
return {};
}
Result<void> ClientConnection::send_error(int error)
{
u8 id = 0;
TRY(m_connection.send_typed(id));
TRY(m_connection.send_typed(error));
return {};
}
Result<OwnedPtr<Client>> Client::connect(StringView path, bool blocking)
{
auto connection = TRY(LocalClient::connect(path, blocking));
return adopt_owned_if_nonnull(new (std::nothrow) Client(move(connection)));
2023-08-14 16:14:35 +00:00
}
Result<void> Client::check_for_messages()
2023-08-14 16:14:35 +00:00
{
if (m_ipc_in_progress)
{
m_ipc_in_progress = false;
m_message_handler(*this, m_ipc_saved_id, m_arg);
return {};
}
2023-08-14 16:14:35 +00:00
u8 id;
auto rc = m_connection->recv_typed(id);
2023-08-14 16:14:35 +00:00
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.
2023-08-14 16:14:35 +00:00
return rc.release_error();
}
m_message_handler(*this, id, m_arg);
return {};
}
Client::Client(OwnedPtr<LocalClient>&& connection) : m_connection(move(connection))
{
2023-08-14 16:14:35 +00:00
}
}