From 551b17591cd25e66b19a98eb56d438bca99a0ec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20S=C3=B6ntgen?= Date: Tue, 17 Nov 2020 14:28:20 +0100 Subject: [PATCH] ssh_terminal: handle detached term in event loop Rather than calling 'ssh_disconnect' from within the Terminal session, flag the detached terminal in the session and let the event loop do the cleanup. Otherwise it might happen that the 'ep' (handling the Terminal session) as well as the 'pthread.0' (executing the ssh event loop) end up both triggering the cleanup concurrently. Issue #3682. --- repos/gems/src/server/ssh_terminal/server.cc | 9 +++++---- repos/gems/src/server/ssh_terminal/server.h | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/repos/gems/src/server/ssh_terminal/server.cc b/repos/gems/src/server/ssh_terminal/server.cc index c14a8e99c5..5b9509f188 100644 --- a/repos/gems/src/server/ssh_terminal/server.cc +++ b/repos/gems/src/server/ssh_terminal/server.cc @@ -376,18 +376,18 @@ void Ssh::Server::detach_terminal(Ssh::Terminal &conn) auto invalidate_terminal = [&] (Session &sess) { Libc::with_libc([&] () { - ssh_blocking_flush(sess.session, 10000); - ssh_disconnect(sess.session); if (sess.terminal != &conn) { return; } sess.terminal = nullptr; + sess.terminal_detached = true; }); }; _sessions.for_each(invalidate_terminal); - _cleanup_sessions(); Libc::with_libc([&] () { Genode::destroy(&_heap, p); }); + + _wake_loop(); } @@ -598,7 +598,8 @@ void Ssh::Server::loop() /* first remove all stale sessions */ auto cleanup = [&] (Session &s) { - if (ssh_is_connected(s.session)) { return ; } + if (!s.terminal_detached + && ssh_is_connected(s.session)) { return ; } _cleanup_session(s); }; _sessions.for_each(cleanup); diff --git a/repos/gems/src/server/ssh_terminal/server.h b/repos/gems/src/server/ssh_terminal/server.h index 1d7f1bae01..76df0e3551 100644 --- a/repos/gems/src/server/ssh_terminal/server.h +++ b/repos/gems/src/server/ssh_terminal/server.h @@ -59,6 +59,7 @@ struct Ssh::Session : Genode::Registry::Element ssh_channel_callbacks channel_cb { nullptr }; Ssh::Terminal *terminal { nullptr }; + bool terminal_detached { false }; Genode::Mutex _access_mutex { }; Genode::Mutex &mutex_terminal()