diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-10-14 21:47:59 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-10-14 21:49:33 +0200 |
commit | 7dbc13ac88fddb29befa8fda16fa37aff9c0d875 (patch) | |
tree | 15bc8682e68a9f402fa14ccbf7ed1f98f39329d6 /Libraries/LibCore/CoreIPCServer.h | |
parent | 735f02900bb3e7e272ff1b96a54e9fa6ba6afb66 (diff) | |
download | serenity-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.h | 35 |
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())); |