1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-23 19:37:34 +00:00

LibIPC: Make IPC::Connection::post_message() return ErrorOr

This commit is contained in:
Andreas Kling 2021-11-28 09:59:36 +01:00
parent 982ac34437
commit 8d76eb773f
4 changed files with 30 additions and 23 deletions

View file

@ -553,7 +553,8 @@ public:
auto result = m_connection.template send_sync_but_allow_failure<Messages::@endpoint.name@::@message.pascal_name@>()~~~"); auto result = m_connection.template send_sync_but_allow_failure<Messages::@endpoint.name@::@message.pascal_name@>()~~~");
} else { } else {
message_generator.append(R"~~~( message_generator.append(R"~~~(
m_connection.post_message(Messages::@endpoint.name@::@message.pascal_name@ { )~~~"); // FIXME: Handle post_message failures.
(void) m_connection.post_message(Messages::@endpoint.name@::@message.pascal_name@ { )~~~");
} }
for (size_t i = 0; i < parameters.size(); ++i) { for (size_t i = 0; i < parameters.size(); ++i) {

View file

@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include <LibCore/System.h>
#include <LibIPC/Connection.h> #include <LibIPC/Connection.h>
#include <LibIPC/Stub.h> #include <LibIPC/Stub.h>
#include <sys/select.h> #include <sys/select.h>
@ -23,28 +24,28 @@ ConnectionBase::~ConnectionBase()
{ {
} }
void ConnectionBase::post_message(Message const& message) ErrorOr<void> ConnectionBase::post_message(Message const& message)
{ {
post_message(message.encode()); return post_message(message.encode());
} }
void ConnectionBase::post_message(MessageBuffer buffer) ErrorOr<void> ConnectionBase::post_message(MessageBuffer buffer)
{ {
// NOTE: If this connection is being shut down, but has not yet been destroyed, // NOTE: If this connection is being shut down, but has not yet been destroyed,
// the socket will be closed. Don't try to send more messages. // the socket will be closed. Don't try to send more messages.
if (!m_socket->is_open()) if (!m_socket->is_open())
return; return Error::from_string_literal("Trying to post_message during IPC shutdown"sv);
// Prepend the message size. // Prepend the message size.
uint32_t message_size = buffer.data.size(); uint32_t message_size = buffer.data.size();
buffer.data.prepend(reinterpret_cast<const u8*>(&message_size), sizeof(message_size)); TRY(buffer.data.try_prepend(reinterpret_cast<const u8*>(&message_size), sizeof(message_size)));
#ifdef __serenity__ #ifdef __serenity__
for (auto& fd : buffer.fds) { for (auto& fd : buffer.fds) {
auto rc = sendfd(m_socket->fd(), fd.value()); if (auto result = Core::System::sendfd(m_socket->fd(), fd.value()); result.is_error()) {
if (rc < 0) { dbgln("{}", result.error());
perror("sendfd");
shutdown(); shutdown();
return result;
} }
} }
#else #else
@ -58,23 +59,21 @@ void ConnectionBase::post_message(MessageBuffer buffer)
if (nwritten < 0) { if (nwritten < 0) {
switch (errno) { switch (errno) {
case EPIPE: case EPIPE:
dbgln("{}::post_message: Disconnected from peer", static_cast<Core::Object const&>(*this));
shutdown(); shutdown();
return; return Error::from_string_literal("IPC::Connection::post_message: Disconnected from peer"sv);
case EAGAIN: case EAGAIN:
dbgln("{}::post_message: Peer buffer overflowed", static_cast<Core::Object const&>(*this));
shutdown(); shutdown();
return; return Error::from_string_literal("IPC::Connection::post_message: Peer buffer overflowed"sv);
default: default:
perror("Connection::post_message write");
shutdown(); shutdown();
return; return Error::from_syscall("IPC::Connection::post_message write"sv, -errno);
} }
} }
total_nwritten += nwritten; total_nwritten += nwritten;
} }
m_responsiveness_timer->start(); m_responsiveness_timer->start();
return {};
} }
void ConnectionBase::shutdown() void ConnectionBase::shutdown()
@ -88,9 +87,13 @@ void ConnectionBase::handle_messages()
{ {
auto messages = move(m_unprocessed_messages); auto messages = move(m_unprocessed_messages);
for (auto& message : messages) { for (auto& message : messages) {
if (message.endpoint_magic() == m_local_endpoint_magic) if (message.endpoint_magic() == m_local_endpoint_magic) {
if (auto response = m_local_stub.handle(message)) if (auto response = m_local_stub.handle(message)) {
post_message(*response); if (auto result = post_message(*response); result.is_error()) {
dbgln("IPC::ConnectionBase::handle_messages: {}", result.error());
}
}
}
} }
} }

View file

@ -33,7 +33,7 @@ public:
virtual ~ConnectionBase() override; virtual ~ConnectionBase() override;
bool is_open() const { return m_socket->is_open(); } bool is_open() const { return m_socket->is_open(); }
void post_message(Message const&); ErrorOr<void> post_message(Message const&);
void shutdown(); void shutdown();
virtual void die() { } virtual void die() { }
@ -52,7 +52,7 @@ protected:
ErrorOr<Vector<u8>> read_as_much_as_possible_from_socket_without_blocking(); ErrorOr<Vector<u8>> read_as_much_as_possible_from_socket_without_blocking();
ErrorOr<void> drain_messages_from_peer(); ErrorOr<void> drain_messages_from_peer();
void post_message(MessageBuffer); ErrorOr<void> post_message(MessageBuffer);
void handle_messages(); void handle_messages();
IPC::Stub& m_local_stub; IPC::Stub& m_local_stub;
@ -90,7 +90,7 @@ public:
template<typename RequestType, typename... Args> template<typename RequestType, typename... Args>
NonnullOwnPtr<typename RequestType::ResponseType> send_sync(Args&&... args) NonnullOwnPtr<typename RequestType::ResponseType> send_sync(Args&&... args)
{ {
post_message(RequestType(forward<Args>(args)...)); MUST(post_message(RequestType(forward<Args>(args)...)));
auto response = wait_for_specific_endpoint_message<typename RequestType::ResponseType, PeerEndpoint>(); auto response = wait_for_specific_endpoint_message<typename RequestType::ResponseType, PeerEndpoint>();
VERIFY(response); VERIFY(response);
return response.release_nonnull(); return response.release_nonnull();
@ -99,7 +99,8 @@ public:
template<typename RequestType, typename... Args> template<typename RequestType, typename... Args>
OwnPtr<typename RequestType::ResponseType> send_sync_but_allow_failure(Args&&... args) OwnPtr<typename RequestType::ResponseType> send_sync_but_allow_failure(Args&&... args)
{ {
post_message(RequestType(forward<Args>(args)...)); if (post_message(RequestType(forward<Args>(args)...)).is_error())
return nullptr;
return wait_for_specific_endpoint_message<typename RequestType::ResponseType, PeerEndpoint>(); return wait_for_specific_endpoint_message<typename RequestType::ResponseType, PeerEndpoint>();
} }

View file

@ -44,7 +44,9 @@ void WMClientConnection::set_applet_area_position(Gfx::IntPoint const& position)
AppletManager::the().set_position(position); AppletManager::the().set_position(position);
WindowServer::ClientConnection::for_each_client([](auto& connection) { WindowServer::ClientConnection::for_each_client([](auto& connection) {
connection.post_message(Messages::WindowClient::AppletAreaRectChanged(AppletManager::the().window()->rect())); if (auto result = connection.post_message(Messages::WindowClient::AppletAreaRectChanged(AppletManager::the().window()->rect())); result.is_error()) {
dbgln("WMClientConnection::set_applet_area_position: {}", result.error());
}
}); });
} }