1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 13:38:11 +00:00

LibCore: Create wake pipe on each thread

After the previous change, the wake pipe was only being created on the
main thread by the main event loop. This change utilizes a flag to
always initialize the wake pipe on other threads. Because the pipe is
quite expensive (it will count towards the file descriptor limit, for
instance), we do the initialization "lazily": Only when an event loop is
constructed and it notices that there hasn't been a wake pipe created on
its thread, it will create the pipe. Conversely, this means that there
are no pipes on threads that never use an event loop.
This commit is contained in:
kleines Filmröllchen 2022-01-02 15:14:25 +01:00 committed by Andreas Kling
parent 69c1910037
commit a501b9c7df
2 changed files with 23 additions and 11 deletions

View file

@ -66,6 +66,23 @@ static thread_local Vector<EventLoop&>* s_event_loop_stack;
static thread_local HashMap<int, NonnullOwnPtr<EventLoopTimer>>* s_timers;
static thread_local HashTable<Notifier*>* s_notifiers;
thread_local int EventLoop::s_wake_pipe_fds[2];
thread_local bool EventLoop::s_wake_pipe_initialized { false };
void EventLoop::initialize_wake_pipes()
{
if (!s_wake_pipe_initialized) {
#if defined(SOCK_NONBLOCK)
int rc = pipe2(s_wake_pipe_fds, O_CLOEXEC);
#else
int rc = pipe(s_wake_pipe_fds);
fcntl(s_wake_pipe_fds[0], F_SETFD, FD_CLOEXEC);
fcntl(s_wake_pipe_fds[1], F_SETFD, FD_CLOEXEC);
#endif
VERIFY(rc == 0);
s_wake_pipe_initialized = true;
}
}
bool EventLoop::has_been_instantiated()
{
@ -273,19 +290,8 @@ EventLoop::EventLoop([[maybe_unused]] MakeInspectable make_inspectable)
}
s_main_event_loop.with_locked([&, this](auto*& main_event_loop) {
if (main_event_loop == nullptr) {
// FIXME: The compiler complains that we don't use main_event_loop although we set it.
main_event_loop = this;
s_pid = getpid();
// FIXME: We only create the wake pipe for the main thread
#if defined(SOCK_NONBLOCK)
int rc = pipe2(s_wake_pipe_fds, O_CLOEXEC);
#else
int rc = pipe(s_wake_pipe_fds);
fcntl(s_wake_pipe_fds[0], F_SETFD, FD_CLOEXEC);
fcntl(s_wake_pipe_fds[1], F_SETFD, FD_CLOEXEC);
#endif
VERIFY(rc == 0);
s_event_loop_stack->append(*this);
#ifdef __serenity__
@ -300,6 +306,8 @@ EventLoop::EventLoop([[maybe_unused]] MakeInspectable make_inspectable)
}
});
initialize_wake_pipes();
dbgln_if(EVENTLOOP_DEBUG, "{} Core::EventLoop constructed :)", getpid());
}
@ -587,6 +595,8 @@ void EventLoop::notify_forked(ForkEvent event)
s_event_loop_stack->clear();
s_timers->clear();
s_notifiers->clear();
s_wake_pipe_initialized = false;
initialize_wake_pipes();
if (auto* info = signals_info<false>()) {
info->signal_handlers.clear();
info->next_signal_id = 0;