Skip to content

src: fix monerod shutdown hanging by making SIGINT handling async-signal-safe#10351

Open
navidR wants to merge 2 commits intomonero-project:masterfrom
navidR:dev/navidr/fix-ctrl-c
Open

src: fix monerod shutdown hanging by making SIGINT handling async-signal-safe#10351
navidR wants to merge 2 commits intomonero-project:masterfrom
navidR:dev/navidr/fix-ctrl-c

Conversation

@navidR
Copy link
Contributor

@navidR navidR commented Mar 6, 2026

This fix annoying issue of Ctrl-C not working. Particularly happens when you are hitting the Ctrl-C at initialization.

@navidR navidR force-pushed the dev/navidr/fix-ctrl-c branch from 13c37b2 to ec48d5e Compare March 6, 2026 16:10
}
const auto remaining = deadline - now;
const auto wait_step = remaining < boost::posix_time::milliseconds(100)
? remaining
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is:

wait_step = std::min(remaining, boost::posix_time::milliseconds(100));

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Fixed.

bool r = local_shared_context->cond.timed_wait(lock, now + wait_step);
if(local_shared_context->ec == boost::asio::error::would_block && !r)
{
continue;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why a continue at the end of the loop?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Fixed. That was a mistake.

}

std::function<void(int)> signal_handler::m_handler;
#ifndef WIN32
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should switch to boost::asio::signal_set while we are hacking away in here. That way we don't need custom platform specific stuff. If we switch to it, we must switch all signal handlers to asio (thats the only catch).

I really don't want another thread for signal handling.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think your suggestion is correct. Therefore, I have switched to boost::asio::signal_set implementation right now.

Without any extra thread for signal handling.

Copy link
Contributor

@vtnerd vtnerd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wish we could reuse existing io_context objects, but that is going to be more difficult. I will look into the overhead of each io_contect object...

std::function<void(int)> signal_handler::m_handler;
boost::mutex signal_handler::m_handler_mutex;
#ifndef WIN32
std::shared_ptr<boost::asio::io_context> signal_handler::m_signal_io;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two (m_signal_io and m_signal_set) should be combined into a single struct instead of allocating them separately.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might make sense to keep them separate if async_wait were capturing the signal_set, but it's not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion; implemented.

#if defined(WIN32)
bool r = TRUE == ::SetConsoleCtrlHandler(&win_handler, TRUE);
if (r)
const bool r = TRUE == ::SetConsoleCtrlHandler(&win_handler, TRUE);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the separate variant for WIN32? boost::asio should handle all cross platform stuff with signal handlers

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or I guess the benefit is the lack of asio needed to do the job?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one, I am hesitant about. Since replacing SetConsoleCtrlHandler with asio on Windows changes signal/control-event semantics.

static boost::mutex m_handler_mutex;

#ifndef WIN32
static std::shared_ptr<boost::asio::io_context> m_signal_io;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move both these variables to the cpp in the anonymous namespace. Then move the header includes to cpp too to reduce header bloat.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion; implemented.

@navidR navidR force-pushed the dev/navidr/fix-ctrl-c branch from fb69629 to 22e89a6 Compare March 7, 2026 11:38
@navidR navidR force-pushed the dev/navidr/fix-ctrl-c branch from 22e89a6 to 0928541 Compare March 8, 2026 12:11
@navidR
Copy link
Contributor Author

navidR commented Mar 8, 2026

@vtnerd I added second commit to fix the DNS wait.

@navidR
Copy link
Contributor Author

navidR commented Mar 8, 2026

Just look at the difference between fix and master:

Fix:
fix

master:
master

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants