summaryrefslogtreecommitdiff
path: root/Libraries/LibCore/CoreIPCServer.h
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-10-14 21:47:59 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-10-14 21:49:33 +0200
commit7dbc13ac88fddb29befa8fda16fa37aff9c0d875 (patch)
tree15bc8682e68a9f402fa14ccbf7ed1f98f39329d6 /Libraries/LibCore/CoreIPCServer.h
parent735f02900bb3e7e272ff1b96a54e9fa6ba6afb66 (diff)
downloadserenity-7dbc13ac88fddb29befa8fda16fa37aff9c0d875.zip
LibCore: Don't crash in IPC client/server on EAGAIN
Instead, just sched_yield() and try again. This makes the WindowServer not fall apart whenever clients take a bit too long to respond. Fixes #656.
Diffstat (limited to 'Libraries/LibCore/CoreIPCServer.h')
-rw-r--r--Libraries/LibCore/CoreIPCServer.h35
1 files changed, 20 insertions, 15 deletions
diff --git a/Libraries/LibCore/CoreIPCServer.h b/Libraries/LibCore/CoreIPCServer.h
index 73b3130379..d5d67619b9 100644
--- a/Libraries/LibCore/CoreIPCServer.h
+++ b/Libraries/LibCore/CoreIPCServer.h
@@ -8,8 +8,8 @@
#include <LibCore/CObject.h>
#include <LibIPC/IEndpoint.h>
#include <LibIPC/IMessage.h>
-
#include <errno.h>
+#include <sched.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
@@ -104,21 +104,26 @@ namespace Server {
++iov_count;
}
- int nwritten = writev(m_socket->fd(), iov, iov_count);
- if (nwritten < 0) {
- switch (errno) {
- case EPIPE:
- dbgprintf("Connection::post_message: Disconnected from peer.\n");
- shutdown();
- return;
- case EAGAIN:
- dbgprintf("Connection::post_message: Client buffer overflowed.\n");
- did_misbehave();
- return;
- default:
- perror("Connection::post_message writev");
- ASSERT_NOT_REACHED();
+ int nwritten = 0;
+ for (;;) {
+ nwritten = writev(m_socket->fd(), iov, iov_count);
+ if (nwritten < 0) {
+ switch (errno) {
+ case EPIPE:
+ dbgprintf("Connection::post_message: Disconnected from peer.\n");
+ shutdown();
+ return;
+ case EAGAIN:
+ // FIXME: It would be better to push these onto a queue so we can go back
+ // to servicing other clients.
+ sched_yield();
+ continue;
+ default:
+ perror("Connection::post_message writev");
+ ASSERT_NOT_REACHED();
+ }
}
+ break;
}
ASSERT(nwritten == (int)(sizeof(message) + extra_data.size()));