Преглед изворни кода

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

Andreas Kling пре 3 година
родитељ
комит
8d76eb773f

+ 2 - 1
Meta/Lagom/Tools/CodeGenerators/IPCCompiler/main.cpp

@@ -553,7 +553,8 @@ public:
         auto result = m_connection.template send_sync_but_allow_failure<Messages::@endpoint.name@::@message.pascal_name@>()~~~");
                 } else {
                     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) {

+ 20 - 17
Userland/Libraries/LibIPC/Connection.cpp

@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: BSD-2-Clause
  */
 
+#include <LibCore/System.h>
 #include <LibIPC/Connection.h>
 #include <LibIPC/Stub.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,
     //       the socket will be closed. Don't try to send more messages.
     if (!m_socket->is_open())
-        return;
+        return Error::from_string_literal("Trying to post_message during IPC shutdown"sv);
 
     // Prepend the message 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__
     for (auto& fd : buffer.fds) {
-        auto rc = sendfd(m_socket->fd(), fd.value());
-        if (rc < 0) {
-            perror("sendfd");
+        if (auto result = Core::System::sendfd(m_socket->fd(), fd.value()); result.is_error()) {
+            dbgln("{}", result.error());
             shutdown();
+            return result;
         }
     }
 #else
@@ -58,23 +59,21 @@ void ConnectionBase::post_message(MessageBuffer buffer)
         if (nwritten < 0) {
             switch (errno) {
             case EPIPE:
-                dbgln("{}::post_message: Disconnected from peer", static_cast<Core::Object const&>(*this));
                 shutdown();
-                return;
+                return Error::from_string_literal("IPC::Connection::post_message: Disconnected from peer"sv);
             case EAGAIN:
-                dbgln("{}::post_message: Peer buffer overflowed", static_cast<Core::Object const&>(*this));
                 shutdown();
-                return;
+                return Error::from_string_literal("IPC::Connection::post_message: Peer buffer overflowed"sv);
             default:
-                perror("Connection::post_message write");
                 shutdown();
-                return;
+                return Error::from_syscall("IPC::Connection::post_message write"sv, -errno);
             }
         }
         total_nwritten += nwritten;
     }
 
     m_responsiveness_timer->start();
+    return {};
 }
 
 void ConnectionBase::shutdown()
@@ -88,9 +87,13 @@ void ConnectionBase::handle_messages()
 {
     auto messages = move(m_unprocessed_messages);
     for (auto& message : messages) {
-        if (message.endpoint_magic() == m_local_endpoint_magic)
-            if (auto response = m_local_stub.handle(message))
-                post_message(*response);
+        if (message.endpoint_magic() == m_local_endpoint_magic) {
+            if (auto response = m_local_stub.handle(message)) {
+                if (auto result = post_message(*response); result.is_error()) {
+                    dbgln("IPC::ConnectionBase::handle_messages: {}", result.error());
+                }
+            }
+        }
     }
 }
 

+ 5 - 4
Userland/Libraries/LibIPC/Connection.h

@@ -33,7 +33,7 @@ public:
     virtual ~ConnectionBase() override;
 
     bool is_open() const { return m_socket->is_open(); }
-    void post_message(Message const&);
+    ErrorOr<void> post_message(Message const&);
 
     void shutdown();
     virtual void die() { }
@@ -52,7 +52,7 @@ protected:
     ErrorOr<Vector<u8>> read_as_much_as_possible_from_socket_without_blocking();
     ErrorOr<void> drain_messages_from_peer();
 
-    void post_message(MessageBuffer);
+    ErrorOr<void> post_message(MessageBuffer);
     void handle_messages();
 
     IPC::Stub& m_local_stub;
@@ -90,7 +90,7 @@ public:
     template<typename RequestType, typename... 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>();
         VERIFY(response);
         return response.release_nonnull();
@@ -99,7 +99,8 @@ public:
     template<typename RequestType, typename... 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>();
     }
 

+ 3 - 1
Userland/Services/WindowServer/WMClientConnection.cpp

@@ -44,7 +44,9 @@ void WMClientConnection::set_applet_area_position(Gfx::IntPoint const& position)
     AppletManager::the().set_position(position);
 
     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());
+        }
     });
 }