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.
This commit is contained in:
Josef Söntgen 2020-11-17 14:28:20 +01:00 committed by Christian Helmuth
parent 51a50ece60
commit 551b17591c
2 changed files with 6 additions and 4 deletions

View File

@ -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);

View File

@ -59,6 +59,7 @@ struct Ssh::Session : Genode::Registry<Session>::Element
ssh_channel_callbacks channel_cb { nullptr };
Ssh::Terminal *terminal { nullptr };
bool terminal_detached { false };
Genode::Mutex _access_mutex { };
Genode::Mutex &mutex_terminal()