diff options
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); + } } |