mirror of
https://github.com/RGBCube/serenity
synced 2025-07-23 18:27:40 +00:00
LibCore: Fix signal handling race condition in EventLoop
The event loop is responsible for handling POSIX signals while it's running. The signal handler adds the signals to a wake pipe which is then read after the select'ing code in wait_for_event. Problems happen, however, when another signal comes in after the select wake: the signal will interrupt the next syscall, the `read` from the wake pipe, and the resulting EINTR in wait_for_event causes the program to crash. This is undesirable. Instead, we want to retry reading as long as we're interrupted.
This commit is contained in:
parent
a501b9c7df
commit
888faa3c9f
1 changed files with 11 additions and 2 deletions
|
@ -5,6 +5,7 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <AK/Assertions.h>
|
||||||
#include <AK/Badge.h>
|
#include <AK/Badge.h>
|
||||||
#include <AK/Debug.h>
|
#include <AK/Debug.h>
|
||||||
#include <AK/Format.h>
|
#include <AK/Format.h>
|
||||||
|
@ -675,9 +676,17 @@ try_select_again:
|
||||||
}
|
}
|
||||||
if (FD_ISSET(s_wake_pipe_fds[0], &rfds)) {
|
if (FD_ISSET(s_wake_pipe_fds[0], &rfds)) {
|
||||||
int wake_events[8];
|
int wake_events[8];
|
||||||
auto nread = read(s_wake_pipe_fds[0], wake_events, sizeof(wake_events));
|
ssize_t nread;
|
||||||
|
// We might receive another signal while read()ing here. The signal will go to the handle_signal properly,
|
||||||
|
// but we get interrupted. Therefore, just retry while we were interrupted.
|
||||||
|
do {
|
||||||
|
errno = 0;
|
||||||
|
nread = read(s_wake_pipe_fds[0], wake_events, sizeof(wake_events));
|
||||||
|
if (nread == 0)
|
||||||
|
break;
|
||||||
|
} while (nread < 0 && errno == EINTR);
|
||||||
if (nread < 0) {
|
if (nread < 0) {
|
||||||
perror("read from wake pipe");
|
perror("Core::EventLoop::wait_for_event: read from wake pipe");
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
VERIFY(nread > 0);
|
VERIFY(nread > 0);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue