From 7d568247e32aa469f259356bf4530762345e47ce Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Sun, 7 Feb 2021 13:58:51 +0100 Subject: [PATCH] wm: fix deadlock in destroy-view handling The deadlock reported in #3236 could be reproduced via the wm.run script and the modification of test/nitpicker in commit "nitpicker: fix destroy with invalid handle" by clicking on the testnit entry of the launchpad. This patch fixes the deadlock by releasing the locked pointer early in the destruction path, which is legitimate as the wm is single-threaded. Fixes #3236 --- repos/gems/src/server/wm/gui.h | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/repos/gems/src/server/wm/gui.h b/repos/gems/src/server/wm/gui.h index fecb14f9f0..05d450bb10 100644 --- a/repos/gems/src/server/wm/gui.h +++ b/repos/gems/src/server/wm/gui.h @@ -920,9 +920,21 @@ class Wm::Gui::Session_component : public Rpc_object, void destroy_view(View_handle handle) override { try { - Locked_ptr view(_view_handle_registry.lookup(handle)); - if (view.valid()) - _destroy_view_object(*view); + /* + * Lookup the view but release the lock to prevent the view + * destructor from taking the lock a second time. The locking + * aspect of the weak ptr is not needed within the wm because + * the component is single-threaded. + */ + View *view_ptr = nullptr; + { + Locked_ptr view(_view_handle_registry.lookup(handle)); + if (view.valid()) + view_ptr = view.operator->(); + } + + if (view_ptr) + _destroy_view_object(*view_ptr); _view_handle_registry.free(handle); } catch (View_handle_registry::Lookup_failed) { }