mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 17:07:34 +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:
parent
735f02900b
commit
7dbc13ac88
2 changed files with 34 additions and 19 deletions
|
@ -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,10 +146,19 @@ namespace Client {
|
||||||
++iov_count;
|
++iov_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nwritten = writev(m_connection->fd(), iov, iov_count);
|
int nwritten;
|
||||||
if (nwritten < 0) {
|
|
||||||
perror("writev");
|
for (;;) {
|
||||||
ASSERT_NOT_REACHED();
|
nwritten = writev(m_connection->fd(), iov, iov_count);
|
||||||
|
if (nwritten < 0) {
|
||||||
|
if (errno == EAGAIN) {
|
||||||
|
sched_yield();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
perror("writev");
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
ASSERT((size_t)nwritten == sizeof(message) + extra_data.size());
|
ASSERT((size_t)nwritten == sizeof(message) + extra_data.size());
|
||||||
|
|
||||||
|
|
|
@ -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,21 +104,26 @@ namespace Server {
|
||||||
++iov_count;
|
++iov_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nwritten = writev(m_socket->fd(), iov, iov_count);
|
int nwritten = 0;
|
||||||
if (nwritten < 0) {
|
for (;;) {
|
||||||
switch (errno) {
|
nwritten = writev(m_socket->fd(), iov, iov_count);
|
||||||
case EPIPE:
|
if (nwritten < 0) {
|
||||||
dbgprintf("Connection::post_message: Disconnected from peer.\n");
|
switch (errno) {
|
||||||
shutdown();
|
case EPIPE:
|
||||||
return;
|
dbgprintf("Connection::post_message: Disconnected from peer.\n");
|
||||||
case EAGAIN:
|
shutdown();
|
||||||
dbgprintf("Connection::post_message: Client buffer overflowed.\n");
|
return;
|
||||||
did_misbehave();
|
case EAGAIN:
|
||||||
return;
|
// FIXME: It would be better to push these onto a queue so we can go back
|
||||||
default:
|
// to servicing other clients.
|
||||||
perror("Connection::post_message writev");
|
sched_yield();
|
||||||
ASSERT_NOT_REACHED();
|
continue;
|
||||||
|
default:
|
||||||
|
perror("Connection::post_message writev");
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(nwritten == (int)(sizeof(message) + extra_data.size()));
|
ASSERT(nwritten == (int)(sizeof(message) + extra_data.size()));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue