From 5c25f0c4db9584adacd8b0446fdc0d5524fe7b31 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 30 Jan 2019 19:35:38 +0100 Subject: [PATCH] Destroy all remaining windows in a process when it dies. --- Kernel/Process.cpp | 8 +++++--- Kernel/Process.h | 1 + Kernel/ProcessGUI.cpp | 9 +++++++++ WindowServer/WSMessage.h | 1 + WindowServer/WSMessageLoop.cpp | 10 ++++++++-- WindowServer/WSMessageLoop.h | 2 +- WindowServer/WSWindow.cpp | 5 +++++ 7 files changed, 30 insertions(+), 6 deletions(-) diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 7abf42786e..62963947bf 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -1490,9 +1490,10 @@ int Process::reap(Process& process) if (process.ppid()) { auto* parent = Process::from_pid(process.ppid()); - ASSERT(parent); - parent->m_ticks_in_user_for_dead_children += process.m_ticks_in_user + process.m_ticks_in_user_for_dead_children; - parent->m_ticks_in_kernel_for_dead_children += process.m_ticks_in_kernel + process.m_ticks_in_kernel_for_dead_children; + if (parent) { + parent->m_ticks_in_user_for_dead_children += process.m_ticks_in_user + process.m_ticks_in_user_for_dead_children; + parent->m_ticks_in_kernel_for_dead_children += process.m_ticks_in_kernel + process.m_ticks_in_kernel_for_dead_children; + } } dbgprintf("reap: %s(%u) {%s}\n", process.name().characters(), process.pid(), toString(process.state())); @@ -2143,4 +2144,5 @@ void Process::die() { set_state(Dead); m_fds.clear(); + destroy_all_windows(); } diff --git a/Kernel/Process.h b/Kernel/Process.h index 66f6676ce4..a17e9da359 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -216,6 +216,7 @@ public: static void initialize(); static void initialize_gui_statics(); int make_window_id(); + void destroy_all_windows(); void crash() NORETURN; static int reap(Process&) WARN_UNUSED_RESULT; diff --git a/Kernel/ProcessGUI.cpp b/Kernel/ProcessGUI.cpp index f5aee91423..db9fd52d56 100644 --- a/Kernel/ProcessGUI.cpp +++ b/Kernel/ProcessGUI.cpp @@ -257,3 +257,12 @@ int Process::gui$set_global_cursor_tracking_enabled(int window_id, bool enabled) window.set_global_cursor_tracking_enabled(enabled); return 0; } + +void Process::destroy_all_windows() +{ + for (auto& it : m_windows) { + auto message = make(WSMessage::WM_DestroyWindow); + WSMessageLoop::the().post_message(it.value.leakPtr(), move(message), true); + } + m_windows.clear(); +} diff --git a/WindowServer/WSMessage.h b/WindowServer/WSMessage.h index 5a15837ef4..87211001b0 100644 --- a/WindowServer/WSMessage.h +++ b/WindowServer/WSMessage.h @@ -14,6 +14,7 @@ public: WM_SetWindowTitle, WM_SetWindowRect, WM_DeferredCompose, + WM_DestroyWindow, MouseMove, MouseDown, MouseUp, diff --git a/WindowServer/WSMessageLoop.cpp b/WindowServer/WSMessageLoop.cpp index f158c861cc..00f4b9a63b 100644 --- a/WindowServer/WSMessageLoop.cpp +++ b/WindowServer/WSMessageLoop.cpp @@ -71,9 +71,15 @@ int WSMessageLoop::exec() } } -void WSMessageLoop::post_message(WSMessageReceiver* receiver, OwnPtr&& message) +void WSMessageLoop::post_message(WSMessageReceiver* receiver, OwnPtr&& message, bool unsafe) { - ASSERT_INTERRUPTS_ENABLED(); + if (unsafe) { + // FIXME: This is such a hack. It should not exist. + m_queued_messages.append({ receiver, move(message) }); + if (current != m_server_process) + m_server_process->request_wakeup(); + return; + } LOCKER(m_lock); #ifdef WSEVENTLOOP_DEBUG dbgprintf("WSMessageLoop::post_message: {%u} << receiver=%p, message=%p\n", m_queued_messages.size(), receiver, message.ptr()); diff --git a/WindowServer/WSMessageLoop.h b/WindowServer/WSMessageLoop.h index e9d32306e0..0d232b7c7b 100644 --- a/WindowServer/WSMessageLoop.h +++ b/WindowServer/WSMessageLoop.h @@ -15,7 +15,7 @@ public: int exec(); - void post_message(WSMessageReceiver* receiver, OwnPtr&&); + void post_message(WSMessageReceiver* receiver, OwnPtr&&, bool unsafe = false); static WSMessageLoop& the(); diff --git a/WindowServer/WSWindow.cpp b/WindowServer/WSWindow.cpp index 81a24ef20e..dfaebea425 100644 --- a/WindowServer/WSWindow.cpp +++ b/WindowServer/WSWindow.cpp @@ -107,12 +107,17 @@ void WSWindow::on_message(WSMessage& message) case WSMessage::WM_SetWindowTitle: set_title(static_cast(message).title()); return; + case WSMessage::WM_DestroyWindow: + delete this; + return; case WSMessage::WindowActivated: gui_event.type = GUI_Event::Type::WindowActivated; break; case WSMessage::WindowDeactivated: gui_event.type = GUI_Event::Type::WindowDeactivated; break; + default: + break; } if (gui_event.type == GUI_Event::Type::Invalid)