mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-27 13:11:46 +03:00
Kernel/Tasks: Allow Kernel processes to be shut down
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.
This commit is contained in:
parent
8940552d1d
commit
021fb3ea05
Notes:
sideshowbarker
2024-07-17 02:42:21 +09:00
Author: https://github.com/kleinesfilmroellchen Commit: https://github.com/SerenityOS/serenity/commit/021fb3ea05 Pull-request: https://github.com/SerenityOS/serenity/pull/19668 Reviewed-by: https://github.com/gmta ✅ Reviewed-by: https://github.com/linusg
@ -586,12 +586,14 @@ size_t UHCIController::poll_transfer_queue(QueueHead& transfer_queue)
|
|||||||
ErrorOr<void> UHCIController::spawn_port_process()
|
ErrorOr<void> UHCIController::spawn_port_process()
|
||||||
{
|
{
|
||||||
TRY(Process::create_kernel_process(TRY(KString::try_create("UHCI Hot Plug Task"sv)), [&] {
|
TRY(Process::create_kernel_process(TRY(KString::try_create("UHCI Hot Plug Task"sv)), [&] {
|
||||||
for (;;) {
|
while (!Process::current().is_dying()) {
|
||||||
if (m_root_hub)
|
if (m_root_hub)
|
||||||
m_root_hub->check_for_port_updates();
|
m_root_hub->check_for_port_updates();
|
||||||
|
|
||||||
(void)Thread::current()->sleep(Duration::from_seconds(1));
|
(void)Thread::current()->sleep(Duration::from_seconds(1));
|
||||||
}
|
}
|
||||||
|
Process::current().sys$exit(0);
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
}));
|
}));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -600,7 +602,7 @@ ErrorOr<void> UHCIController::spawn_async_poll_process()
|
|||||||
{
|
{
|
||||||
TRY(Process::create_kernel_process(TRY(KString::try_create("UHCI Async Poll Task"sv)), [&] {
|
TRY(Process::create_kernel_process(TRY(KString::try_create("UHCI Async Poll Task"sv)), [&] {
|
||||||
u16 poll_interval_ms = 1024;
|
u16 poll_interval_ms = 1024;
|
||||||
for (;;) {
|
while (!Process::current().is_dying()) {
|
||||||
{
|
{
|
||||||
SpinlockLocker locker { m_async_lock };
|
SpinlockLocker locker { m_async_lock };
|
||||||
for (OwnPtr<AsyncTransferHandle>& handle : m_active_async_transfers) {
|
for (OwnPtr<AsyncTransferHandle>& handle : m_active_async_transfers) {
|
||||||
@ -618,6 +620,8 @@ ErrorOr<void> UHCIController::spawn_async_poll_process()
|
|||||||
}
|
}
|
||||||
(void)Thread::current()->sleep(Duration::from_milliseconds(poll_interval_ms));
|
(void)Thread::current()->sleep(Duration::from_milliseconds(poll_interval_ms));
|
||||||
}
|
}
|
||||||
|
Process::current().sys$exit(0);
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
}));
|
}));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -327,7 +327,7 @@ size_t Plan9FS::adjust_buffer_size(size_t size) const
|
|||||||
void Plan9FS::thread_main()
|
void Plan9FS::thread_main()
|
||||||
{
|
{
|
||||||
dbgln("Plan9FS: Thread running");
|
dbgln("Plan9FS: Thread running");
|
||||||
do {
|
while (!Process::current().is_dying()) {
|
||||||
auto result = read_and_dispatch_one_message();
|
auto result = read_and_dispatch_one_message();
|
||||||
if (result.is_error()) {
|
if (result.is_error()) {
|
||||||
// If we fail to read, wake up everyone with an error.
|
// If we fail to read, wake up everyone with an error.
|
||||||
@ -342,7 +342,7 @@ void Plan9FS::thread_main()
|
|||||||
dbgln("Plan9FS: Thread terminating, error reading");
|
dbgln("Plan9FS: Thread terminating, error reading");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} while (!m_thread_shutdown);
|
}
|
||||||
dbgln("Plan9FS: Thread terminating");
|
dbgln("Plan9FS: Thread terminating");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,6 +356,8 @@ void Plan9FS::ensure_thread()
|
|||||||
auto [_, thread] = Process::create_kernel_process(process_name.release_value(), [&]() {
|
auto [_, thread] = Process::create_kernel_process(process_name.release_value(), [&]() {
|
||||||
thread_main();
|
thread_main();
|
||||||
m_thread_running.store(false, AK::MemoryOrder::memory_order_release);
|
m_thread_running.store(false, AK::MemoryOrder::memory_order_release);
|
||||||
|
Process::current().sys$exit(0);
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
}).release_value_but_fixme_should_propagate_errors();
|
}).release_value_but_fixme_should_propagate_errors();
|
||||||
m_thread = move(thread);
|
m_thread = move(thread);
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,6 @@ private:
|
|||||||
Spinlock<LockRank::None> m_thread_lock {};
|
Spinlock<LockRank::None> m_thread_lock {};
|
||||||
RefPtr<Thread> m_thread;
|
RefPtr<Thread> m_thread;
|
||||||
Atomic<bool> m_thread_running { false };
|
Atomic<bool> m_thread_running { false };
|
||||||
Atomic<bool, AK::MemoryOrder::memory_order_relaxed> m_thread_shutdown { false };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ void NetworkTask_main(void*)
|
|||||||
auto buffer = (u8*)buffer_region->vaddr().get();
|
auto buffer = (u8*)buffer_region->vaddr().get();
|
||||||
UnixDateTime packet_timestamp;
|
UnixDateTime packet_timestamp;
|
||||||
|
|
||||||
for (;;) {
|
while (!Process::current().is_dying()) {
|
||||||
flush_delayed_tcp_acks();
|
flush_delayed_tcp_acks();
|
||||||
retransmit_tcp_packets();
|
retransmit_tcp_packets();
|
||||||
size_t packet_size = dequeue_packet(buffer, buffer_size, packet_timestamp);
|
size_t packet_size = dequeue_packet(buffer, buffer_size, packet_timestamp);
|
||||||
@ -127,6 +127,8 @@ void NetworkTask_main(void*)
|
|||||||
dbgln_if(ETHERNET_DEBUG, "NetworkTask: Unknown ethernet type {:#04x}", eth.ether_type());
|
dbgln_if(ETHERNET_DEBUG, "NetworkTask: Unknown ethernet type {:#04x}", eth.ether_type());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Process::current().sys$exit(0);
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_arp(EthernetFrameHeader const& eth, size_t frame_size)
|
void handle_arp(EthernetFrameHeader const& eth, size_t frame_size)
|
||||||
|
@ -16,7 +16,7 @@ static constexpr StringView finalizer_task_name = "Finalizer Task"sv;
|
|||||||
static void finalizer_task(void*)
|
static void finalizer_task(void*)
|
||||||
{
|
{
|
||||||
Thread::current()->set_priority(THREAD_PRIORITY_LOW);
|
Thread::current()->set_priority(THREAD_PRIORITY_LOW);
|
||||||
for (;;) {
|
while (!Process::current().is_dying()) {
|
||||||
// The order of this if-else is important: We want to continue trying to finalize the threads in case
|
// The order of this if-else is important: We want to continue trying to finalize the threads in case
|
||||||
// Thread::finalize_dying_threads set g_finalizer_has_work back to true due to OOM conditions
|
// Thread::finalize_dying_threads set g_finalizer_has_work back to true due to OOM conditions
|
||||||
if (g_finalizer_has_work.exchange(false, AK::MemoryOrder::memory_order_acq_rel) == true)
|
if (g_finalizer_has_work.exchange(false, AK::MemoryOrder::memory_order_acq_rel) == true)
|
||||||
@ -24,6 +24,8 @@ static void finalizer_task(void*)
|
|||||||
else
|
else
|
||||||
g_finalizer_wait_queue->wait_forever(finalizer_task_name);
|
g_finalizer_wait_queue->wait_forever(finalizer_task_name);
|
||||||
}
|
}
|
||||||
|
Process::current().sys$exit(0);
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
UNMAP_AFTER_INIT void FinalizerTask::spawn()
|
UNMAP_AFTER_INIT void FinalizerTask::spawn()
|
||||||
|
@ -16,10 +16,12 @@ UNMAP_AFTER_INIT void SyncTask::spawn()
|
|||||||
{
|
{
|
||||||
MUST(Process::create_kernel_process(KString::must_create("VFS Sync Task"sv), [] {
|
MUST(Process::create_kernel_process(KString::must_create("VFS Sync Task"sv), [] {
|
||||||
dbgln("VFS SyncTask is running");
|
dbgln("VFS SyncTask is running");
|
||||||
for (;;) {
|
while (!Process::current().is_dying()) {
|
||||||
VirtualFileSystem::sync();
|
VirtualFileSystem::sync();
|
||||||
(void)Thread::current()->sleep(Duration::from_seconds(1));
|
(void)Thread::current()->sleep(Duration::from_seconds(1));
|
||||||
}
|
}
|
||||||
|
Process::current().sys$exit(0);
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ UNMAP_AFTER_INIT WorkQueue::WorkQueue(StringView name)
|
|||||||
if (name_kstring.is_error())
|
if (name_kstring.is_error())
|
||||||
TODO();
|
TODO();
|
||||||
auto [_, thread] = Process::create_kernel_process(name_kstring.release_value(), [this] {
|
auto [_, thread] = Process::create_kernel_process(name_kstring.release_value(), [this] {
|
||||||
for (;;) {
|
while (!Process::current().is_dying()) {
|
||||||
WorkItem* item;
|
WorkItem* item;
|
||||||
bool have_more;
|
bool have_more;
|
||||||
m_items.with([&](auto& items) {
|
m_items.with([&](auto& items) {
|
||||||
@ -44,6 +44,8 @@ UNMAP_AFTER_INIT WorkQueue::WorkQueue(StringView name)
|
|||||||
}
|
}
|
||||||
[[maybe_unused]] auto result = m_wait_queue.wait_on({});
|
[[maybe_unused]] auto result = m_wait_queue.wait_on({});
|
||||||
}
|
}
|
||||||
|
Process::current().sys$exit(0);
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
}).release_value_but_fixme_should_propagate_errors();
|
}).release_value_but_fixme_should_propagate_errors();
|
||||||
m_thread = move(thread);
|
m_thread = move(thread);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user