diff options
author | Andreas Kling <kling@serenityos.org> | 2021-07-04 18:01:01 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-07-04 18:56:08 +0200 |
commit | e8579ed24a00e95deabbcfe3486d73ca541bc68c (patch) | |
tree | 39705174be706443308ee759420e3511b3f7b913 /Userland/Libraries/LibThreading/BackgroundAction.cpp | |
parent | d114ba4c4e52d52755ad8b874e3ab4ec67b794e7 (diff) | |
download | serenity-e8579ed24a00e95deabbcfe3486d73ca541bc68c.zip |
LibThreading: Wake up the background worker thread when there's work
The worker thread used for BackgroundAction was going to sleep for
1 second at a time (when there was nothing to do.) This made using
background actions for anything interactive quite unresponsive since
you had to wait up to 1 second before it even started on your task.
We now use a simple Unix pipe to signal the worker thread that a new
work item is available.
This makes Assistant way more responsive when typing. :^)
Diffstat (limited to 'Userland/Libraries/LibThreading/BackgroundAction.cpp')
-rw-r--r-- | Userland/Libraries/LibThreading/BackgroundAction.cpp | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/Userland/Libraries/LibThreading/BackgroundAction.cpp b/Userland/Libraries/LibThreading/BackgroundAction.cpp index 7e95cec977..5ddcb84ec5 100644 --- a/Userland/Libraries/LibThreading/BackgroundAction.cpp +++ b/Userland/Libraries/LibThreading/BackgroundAction.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org> + * Copyright (c) 2021, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -8,24 +9,33 @@ #include <LibThreading/BackgroundAction.h> #include <LibThreading/Lock.h> #include <LibThreading/Thread.h> +#include <unistd.h> static Threading::Lockable<Queue<Function<void()>>>* s_all_actions; static Threading::Thread* s_background_thread; +static int s_notify_pipe_fds[2]; static intptr_t background_thread_func() { while (true) { - Function<void()> work_item; + char buffer[1]; + auto nread = read(s_notify_pipe_fds[0], buffer, sizeof(buffer)); + if (nread < 0) { + perror("read"); + _exit(1); + } + + Vector<Function<void()>> work_items; { Threading::Locker locker(s_all_actions->lock()); - if (!s_all_actions->resource().is_empty()) - work_item = s_all_actions->resource().dequeue(); + while (!s_all_actions->resource().is_empty()) { + work_items.append(s_all_actions->resource().dequeue()); + } } - if (work_item) + + for (auto& work_item : work_items) work_item(); - else - sleep(1); } VERIFY_NOT_REACHED(); @@ -33,22 +43,32 @@ static intptr_t background_thread_func() static void init() { + if (pipe(s_notify_pipe_fds) < 0) { + perror("pipe"); + _exit(1); + } s_all_actions = new Threading::Lockable<Queue<Function<void()>>>(); s_background_thread = &Threading::Thread::construct(background_thread_func).leak_ref(); s_background_thread->set_name("Background thread"); s_background_thread->start(); } -Threading::Lockable<Queue<Function<void()>>>& Threading::BackgroundActionBase::all_actions() +Threading::Thread& Threading::BackgroundActionBase::background_thread() { - if (s_all_actions == nullptr) + if (s_background_thread == nullptr) init(); - return *s_all_actions; + return *s_background_thread; } -Threading::Thread& Threading::BackgroundActionBase::background_thread() +void Threading::BackgroundActionBase::enqueue_work(Function<void()> work) { - if (s_background_thread == nullptr) + if (s_all_actions == nullptr) init(); - return *s_background_thread; + Locker locker(s_all_actions->lock()); + s_all_actions->resource().enqueue(move(work)); + char ch = 'x'; + if (write(s_notify_pipe_fds[1], &ch, sizeof(ch)) < 0) { + perror("write"); + _exit(1); + } } |