mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 06:27:45 +00:00
LibIPC: Handle ECONNRESET
when reading from the IPC socket
Reading from a socket with a dead peer returns the `ECONNRESET` error code in some cases on Linux. This commit changes LibIPC to gracefully shut down the socket if that happens, fixing an occasional crash in Ladybird. Fixes SerenityOS/ladybird#116
This commit is contained in:
parent
45108438ce
commit
efaf9f137a
1 changed files with 18 additions and 6 deletions
|
@ -157,6 +157,15 @@ ErrorOr<Vector<u8>> ConnectionBase::read_as_much_as_possible_from_socket_without
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 buffer[4096];
|
u8 buffer[4096];
|
||||||
|
|
||||||
|
bool should_shut_down = false;
|
||||||
|
auto schedule_shutdown = [this, &should_shut_down]() {
|
||||||
|
should_shut_down = true;
|
||||||
|
m_deferred_invoker->schedule([strong_this = NonnullRefPtr(*this)] {
|
||||||
|
strong_this->shutdown();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
while (m_socket->is_open()) {
|
while (m_socket->is_open()) {
|
||||||
auto maybe_bytes_read = m_socket->read_without_waiting({ buffer, 4096 });
|
auto maybe_bytes_read = m_socket->read_without_waiting({ buffer, 4096 });
|
||||||
if (maybe_bytes_read.is_error()) {
|
if (maybe_bytes_read.is_error()) {
|
||||||
|
@ -165,6 +174,11 @@ ErrorOr<Vector<u8>> ConnectionBase::read_as_much_as_possible_from_socket_without
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (error.is_syscall() && error.code() == ECONNRESET) {
|
||||||
|
schedule_shutdown();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
dbgln("ConnectionBase::read_as_much_as_possible_from_socket_without_blocking: {}", error);
|
dbgln("ConnectionBase::read_as_much_as_possible_from_socket_without_blocking: {}", error);
|
||||||
warnln("ConnectionBase::read_as_much_as_possible_from_socket_without_blocking: {}", error);
|
warnln("ConnectionBase::read_as_much_as_possible_from_socket_without_blocking: {}", error);
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
|
@ -172,12 +186,8 @@ ErrorOr<Vector<u8>> ConnectionBase::read_as_much_as_possible_from_socket_without
|
||||||
|
|
||||||
auto bytes_read = maybe_bytes_read.release_value();
|
auto bytes_read = maybe_bytes_read.release_value();
|
||||||
if (bytes_read.is_empty()) {
|
if (bytes_read.is_empty()) {
|
||||||
m_deferred_invoker->schedule([strong_this = NonnullRefPtr(*this)] {
|
schedule_shutdown();
|
||||||
strong_this->shutdown();
|
break;
|
||||||
});
|
|
||||||
if (!bytes.is_empty())
|
|
||||||
break;
|
|
||||||
return Error::from_string_literal("IPC connection EOF");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes.append(bytes_read.data(), bytes_read.size());
|
bytes.append(bytes_read.data(), bytes_read.size());
|
||||||
|
@ -186,6 +196,8 @@ ErrorOr<Vector<u8>> ConnectionBase::read_as_much_as_possible_from_socket_without
|
||||||
if (!bytes.is_empty()) {
|
if (!bytes.is_empty()) {
|
||||||
m_responsiveness_timer->stop();
|
m_responsiveness_timer->stop();
|
||||||
did_become_responsive();
|
did_become_responsive();
|
||||||
|
} else if (should_shut_down) {
|
||||||
|
return Error::from_string_literal("IPC connection EOF");
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytes;
|
return bytes;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue