Serenity Operating System
at master 64 lines 1.7 kB view raw
1/* 2 * Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org> 3 * Copyright (c) 2021, Andreas Kling <kling@serenityos.org> 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8#include <AK/Queue.h> 9#include <LibThreading/BackgroundAction.h> 10#include <LibThreading/Mutex.h> 11#include <LibThreading/Thread.h> 12#include <unistd.h> 13 14static pthread_mutex_t s_mutex = PTHREAD_MUTEX_INITIALIZER; 15static pthread_cond_t s_condition = PTHREAD_COND_INITIALIZER; 16static Queue<Function<void()>>* s_all_actions; 17static Threading::Thread* s_background_thread; 18 19static intptr_t background_thread_func() 20{ 21 Vector<Function<void()>> actions; 22 while (true) { 23 24 pthread_mutex_lock(&s_mutex); 25 26 while (s_all_actions->is_empty()) 27 pthread_cond_wait(&s_condition, &s_mutex); 28 29 while (!s_all_actions->is_empty()) 30 actions.append(s_all_actions->dequeue()); 31 32 pthread_mutex_unlock(&s_mutex); 33 34 for (auto& action : actions) 35 action(); 36 37 actions.clear(); 38 } 39} 40 41static void init() 42{ 43 s_all_actions = new Queue<Function<void()>>; 44 s_background_thread = &Threading::Thread::construct(background_thread_func, "Background Thread"sv).leak_ref(); 45 s_background_thread->start(); 46} 47 48Threading::Thread& Threading::BackgroundActionBase::background_thread() 49{ 50 if (s_background_thread == nullptr) 51 init(); 52 return *s_background_thread; 53} 54 55void Threading::BackgroundActionBase::enqueue_work(Function<void()> work) 56{ 57 if (s_all_actions == nullptr) 58 init(); 59 60 pthread_mutex_lock(&s_mutex); 61 s_all_actions->enqueue(move(work)); 62 pthread_cond_broadcast(&s_condition); 63 pthread_mutex_unlock(&s_mutex); 64}