mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 09:48:11 +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
|
||||
*/
|
||||
|
||||
#include <AK/Assertions.h>
|
||||
#include <AK/Badge.h>
|
||||
#include <AK/Debug.h>
|
||||
#include <AK/Format.h>
|
||||
|
@ -675,9 +676,17 @@ try_select_again:
|
|||
}
|
||||
if (FD_ISSET(s_wake_pipe_fds[0], &rfds)) {
|
||||
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) {
|
||||
perror("read from wake pipe");
|
||||
perror("Core::EventLoop::wait_for_event: read from wake pipe");
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
VERIFY(nread > 0);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue