mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-23 09:46:04 -05:00
021fb3ea05
Since we never check a kernel process's state like a userland process, it's possible for a kernel process to ignore the fact that someone is trying to kill it, and continue running. This is not desireable if we want to properly shutdown all processes, including Kernel ones.
61 lines
1.6 KiB
C++
61 lines
1.6 KiB
C++
/*
|
|
* Copyright (c) 2021, the SerenityOS developers.
|
|
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <Kernel/Arch/Processor.h>
|
|
#include <Kernel/Sections.h>
|
|
#include <Kernel/Tasks/Process.h>
|
|
#include <Kernel/Tasks/WaitQueue.h>
|
|
#include <Kernel/Tasks/WorkQueue.h>
|
|
|
|
namespace Kernel {
|
|
|
|
WorkQueue* g_io_work;
|
|
WorkQueue* g_ata_work;
|
|
|
|
UNMAP_AFTER_INIT void WorkQueue::initialize()
|
|
{
|
|
g_io_work = new WorkQueue("IO WorkQueue Task"sv);
|
|
g_ata_work = new WorkQueue("ATA WorkQueue Task"sv);
|
|
}
|
|
|
|
UNMAP_AFTER_INIT WorkQueue::WorkQueue(StringView name)
|
|
{
|
|
auto name_kstring = KString::try_create(name);
|
|
if (name_kstring.is_error())
|
|
TODO();
|
|
auto [_, thread] = Process::create_kernel_process(name_kstring.release_value(), [this] {
|
|
while (!Process::current().is_dying()) {
|
|
WorkItem* item;
|
|
bool have_more;
|
|
m_items.with([&](auto& items) {
|
|
item = items.take_first();
|
|
have_more = !items.is_empty();
|
|
});
|
|
if (item) {
|
|
item->function();
|
|
delete item;
|
|
|
|
if (have_more)
|
|
continue;
|
|
}
|
|
[[maybe_unused]] auto result = m_wait_queue.wait_on({});
|
|
}
|
|
Process::current().sys$exit(0);
|
|
VERIFY_NOT_REACHED();
|
|
}).release_value_but_fixme_should_propagate_errors();
|
|
m_thread = move(thread);
|
|
}
|
|
|
|
void WorkQueue::do_queue(WorkItem& item)
|
|
{
|
|
m_items.with([&](auto& items) {
|
|
items.append(item);
|
|
});
|
|
m_wait_queue.wake_one();
|
|
}
|
|
|
|
}
|