Browse Source

LibIPC: Retry post_message write on EAGAIN and yield

This is a quick and dirty fix to at least get the Inspector working
again. This is a very bad solution long term, because it will spin on
the EventLoop. That is why there is a message reminding everyone this
problem still needs to be fixed, every time this is actually done.
FrHun 3 years ago
parent
commit
96276c87cf
1 changed files with 12 additions and 0 deletions
  1. 12 0
      Userland/Libraries/LibIPC/Connection.cpp

+ 12 - 0
Userland/Libraries/LibIPC/Connection.cpp

@@ -49,11 +49,20 @@ ErrorOr<void> ConnectionBase::post_message(MessageBuffer buffer)
 #endif
 #endif
 
 
     ReadonlyBytes bytes_to_write { buffer.data.span() };
     ReadonlyBytes bytes_to_write { buffer.data.span() };
+    int writes_done = 0;
+    size_t initial_size = bytes_to_write.size();
     while (!bytes_to_write.is_empty()) {
     while (!bytes_to_write.is_empty()) {
         auto maybe_nwritten = m_socket->write(bytes_to_write);
         auto maybe_nwritten = m_socket->write(bytes_to_write);
+        writes_done++;
         if (maybe_nwritten.is_error()) {
         if (maybe_nwritten.is_error()) {
             auto error = maybe_nwritten.release_error();
             auto error = maybe_nwritten.release_error();
             if (error.is_errno()) {
             if (error.is_errno()) {
+                // FIXME: This is a hacky way to at least not crash on large messages
+                // The limit of 100 writes is arbitrary, and there to prevent indefinite spinning on the EventLoop
+                if (error.code() == EAGAIN && writes_done < 100) {
+                    sched_yield();
+                    continue;
+                }
                 shutdown_with_error(error);
                 shutdown_with_error(error);
                 switch (error.code()) {
                 switch (error.code()) {
                 case EPIPE:
                 case EPIPE:
@@ -70,6 +79,9 @@ ErrorOr<void> ConnectionBase::post_message(MessageBuffer buffer)
 
 
         bytes_to_write = bytes_to_write.slice(maybe_nwritten.value());
         bytes_to_write = bytes_to_write.slice(maybe_nwritten.value());
     }
     }
+    if (writes_done > 1) {
+        dbgln("LibIPC::Connection FIXME Warning, needed {} writes needed to send message of size {}B, this is pretty bad, as it spins on the EventLoop", writes_done, initial_size);
+    }
 
 
     m_responsiveness_timer->start();
     m_responsiveness_timer->start();
     return {};
     return {};