1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 09:07:35 +00:00

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.
This commit is contained in:
Andreas Kling 2019-10-14 21:47:59 +02:00
parent 735f02900b
commit 7dbc13ac88
2 changed files with 34 additions and 19 deletions

View file

@ -6,6 +6,7 @@
#include <LibCore/CNotifier.h> #include <LibCore/CNotifier.h>
#include <LibCore/CSyscallUtils.h> #include <LibCore/CSyscallUtils.h>
#include <LibIPC/IMessage.h> #include <LibIPC/IMessage.h>
#include <sched.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/select.h> #include <sys/select.h>
@ -145,11 +146,20 @@ namespace Client {
++iov_count; ++iov_count;
} }
int nwritten = writev(m_connection->fd(), iov, iov_count); int nwritten;
for (;;) {
nwritten = writev(m_connection->fd(), iov, iov_count);
if (nwritten < 0) { if (nwritten < 0) {
if (errno == EAGAIN) {
sched_yield();
continue;
}
perror("writev"); perror("writev");
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
} }
break;
}
ASSERT((size_t)nwritten == sizeof(message) + extra_data.size()); ASSERT((size_t)nwritten == sizeof(message) + extra_data.size());
return true; return true;

View file

@ -8,8 +8,8 @@
#include <LibCore/CObject.h> #include <LibCore/CObject.h>
#include <LibIPC/IEndpoint.h> #include <LibIPC/IEndpoint.h>
#include <LibIPC/IMessage.h> #include <LibIPC/IMessage.h>
#include <errno.h> #include <errno.h>
#include <sched.h>
#include <stdio.h> #include <stdio.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/types.h> #include <sys/types.h>
@ -104,7 +104,9 @@ namespace Server {
++iov_count; ++iov_count;
} }
int nwritten = writev(m_socket->fd(), iov, iov_count); int nwritten = 0;
for (;;) {
nwritten = writev(m_socket->fd(), iov, iov_count);
if (nwritten < 0) { if (nwritten < 0) {
switch (errno) { switch (errno) {
case EPIPE: case EPIPE:
@ -112,14 +114,17 @@ namespace Server {
shutdown(); shutdown();
return; return;
case EAGAIN: case EAGAIN:
dbgprintf("Connection::post_message: Client buffer overflowed.\n"); // FIXME: It would be better to push these onto a queue so we can go back
did_misbehave(); // to servicing other clients.
return; sched_yield();
continue;
default: default:
perror("Connection::post_message writev"); perror("Connection::post_message writev");
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
} }
} }
break;
}
ASSERT(nwritten == (int)(sizeof(message) + extra_data.size())); ASSERT(nwritten == (int)(sizeof(message) + extra_data.size()));
} }