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
|
|
|
|
{
|
2024-02-03 18:16:39 +00:00
|
|
|
Result<OwnedPtr<ClientConnection>> ClientConnection::adopt_connection(LocalServer::Client&& connection)
|
2023-08-14 16:14:35 +00:00
|
|
|
{
|
2024-02-03 18:16:39 +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;
|
2024-02-03 18:16:39 +00:00
|
|
|
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.
|
2023-08-16 14:48:39 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2024-02-03 18:16:39 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2024-02-03 18:16:39 +00:00
|
|
|
Result<void> Client::check_for_messages()
|
2023-08-14 16:14:35 +00:00
|
|
|
{
|
2024-02-03 18:16:39 +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;
|
2024-02-03 18:16:39 +00:00
|
|
|
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.
|
2023-08-16 14:48:39 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2024-02-03 18:16:39 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
}
|