mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-05 17:52:29 +00:00
control: close directory watch on quick shutdown (fix SIGABRT at exit)
Control::handle_shutdown() closes m_directory_events (the inotify directory
watch) only in the normal-shutdown branch (!m_shutdownQuick). On a quick
shutdown (SIGTERM -> receive_quick_shutdown) the m_shutdownQuick branch skips
it, so the watch stays registered in the poll. ~Control() then destroys the
still-open directory_events and Event::~Event()'s assert(m_poll_event == nullptr)
(added with the 0.16.13 poll/event rework) aborts:
main -> Control::~Control() -> ~directory_events -> ~Event() -> abort
Close it in Control::cleanup() instead, which runs on every shutdown path after
the session is saved; close() is idempotent, so the normal path that already
closed it in handle_shutdown() is unaffected.
Reproducible: configure a directory.watch.added watch, then SIGTERM the client
-> SIGABRT (core in Event::~Event); SIGINT (normal shutdown) is clean. With this
change SIGTERM exits cleanly too.
This commit is contained in:
committed by
Jari Sundell
parent
a79aaad9ab
commit
517454b413
@@ -88,6 +88,15 @@ Control::cleanup() {
|
||||
if(!display::Canvas::daemon())
|
||||
m_inputStdin->remove();
|
||||
|
||||
// Close the directory watch (inotify) Event on every shutdown path.
|
||||
// handle_shutdown() only closes it on a normal shutdown; a quick shutdown
|
||||
// (SIGTERM -> receive_quick_shutdown) takes the m_shutdownQuick branch and
|
||||
// skips it, leaving directory_events registered in the poll. ~Control() would
|
||||
// then destroy it while still open and trip the Event::~Event() assert
|
||||
// (m_poll_event == nullptr) -> SIGABRT. close() is idempotent (no-op when the
|
||||
// normal path already closed it).
|
||||
m_directory_events->close();
|
||||
|
||||
if (scgi_thread::thread()->is_active())
|
||||
scgi_thread::thread()->stop_thread_wait();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user