Skip to content

Interactive runner can hang on shutdown while debug pump is blocked in accept() #4

Description

@MysteriousAeon

On Linux, the interactive runner can hang indefinitely after the SDL frontend has already closed.

I reproduced this while testing MetroidPrimeHuntersRecomp against ndsrecomp commit 46b12e6c18dea47f87d2c1f98c3054149dcbca5d.

Observed behavior after exiting normally with Esc:

[sdl] closed after 1731 presented frames

The window closes, but the process never exits and has to be interrupted manually.

While the process was hung, the main thread was waiting on a futex and the debug pump thread was blocked in accept():

PID      TID STAT WCHAN
...      ... S<l+ futex_wait
...      ... S<l+ inet_csk_accept
...      ... S<l+ futex_wait

The play-mode debug listener was also still present:

LISTEN 0 1 127.0.0.1:19842 0.0.0.0:*

debug_pump_stop() currently sets the shutdown flag and closes the listening socket before joining the pump thread:

g_pump_shutdown.store(true, std::memory_order_relaxed);
CLOSESOCK(g_pump_listener);
g_pump_listener = INVALID_SOCKET;
...
if (g_pump_thread.joinable()) g_pump_thread.join();

On Linux, closing the listener from another thread did not wake the blocking accept() in this reproduction, so the join never completed.

As a local test, I explicitly shut down the listening socket before closing it:

#ifdef _WIN32
    shutdown(g_pump_listener, SD_BOTH);
#else
    shutdown(g_pump_listener, SHUT_RDWR);
#endif
CLOSESOCK(g_pump_listener);

With that change, the same test exits cleanly:

[sdl] closed after 627 presented frames
runner exit=0

So explicitly shutting down the listener appears to reliably unblock the pump thread before joining it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions