Skip to content

Conversation

@rajatarya
Copy link
Collaborator

@rajatarya rajatarya commented Dec 3, 2025

  • On Unix restores the previous SIGINT handler, on Windows deregisters handler
  • attempts to call winapi directly as unsafe block to allow deregistering ctrl+c handler

Fixes #585

Coded with assistance from AI (Cursor/Composer).

@rajatarya rajatarya requested a review from hoytak December 3, 2025 18:52
@rajatarya
Copy link
Collaborator Author

I've tested this with a local hf-xet build following the GH issue repro steps - and now CTRL+C correctly stops Uvicorn process on Windows. Will test on MacOS and then clean up the code before marking PR ready for review.

@rajatarya
Copy link
Collaborator Author

OK tested on MacOS and see the expected CTRL+C behavior, when running Univorn after download is complete, hitting CTRL+C successfully exits the Python process.

Also verified that while downloading model file pressing CTRL+C results in download cancelation.

@rajatarya rajatarya marked this pull request as ready for review December 3, 2025 22:56
@rajatarya rajatarya changed the title WIP: SIGINT handler registration controller (supports deregister) SIGINT handler registration controller (supports deregister) Dec 3, 2025
- attempts to call winapi directly as unsafe block to allow
  deregistering ctrl+c handler
@rajatarya rajatarya force-pushed the rajat/sigint_handler_unregister branch from 6d69992 to c88c73f Compare December 3, 2025 23:01
Copy link
Collaborator

@hoytak hoytak left a comment

Choose a reason for hiding this comment

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

So I don't think registering and deregistering the signal handle is the correct approach for two reasons:

  1. There is a fundamental race condition here in that external_executor_count can be incremented at any point. As written, it can increment to one while we're deregistering the signal handler, which would leave it in a bad state. So it's problematic to do this.
  2. Registering a signal handler in the way we do it doesn't replace the previous ones, it just chains them. So the others get called. However, this is more subtle and here we find the root of the windows issues people discovered:
  • On unix, all the installed signal handlers are called when they are registered using the current method. Since our signal handler does nothing but set an atomic, there's no reason to deregister it; the python or other signal handlers will get called immediately after that. That's one of the reasons it is so simple and all the logic is elsewhere.
  • On windows, other signal handlers are also chained, but it's more subtle here as signal handlers are called in reverse order of installation until one returns true, which is the of the problem that we're trying to fix.

Digging into this a bit more, the ctrlc package signal handler returns true on windows, which blocks the other handers from being called. Thus the actual here fix is to change the windows handler to just set the SIGINT_DETECTED flag and always return false, allowing other handers to do the rest of the work there. We shouldn't have to change the
unix code at all.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

hf-xet SIGINT handler remains registered after completing operation (download/upload)

3 participants