Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not join threads on process exit #1738

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

zcbenz
Copy link
Contributor

@zcbenz zcbenz commented Dec 30, 2024

On Windows the process hangs on exit after running some ops, after some debugging I found that it stuck at the synchronize call in ~StreamThread, which was because the thread was already terminated by OS on process exit.

C++ does not seem to specify when threads are terminated during process exit, but at least on Windows the destructors of static objects are called after the stream threads get terminated, resulting in posting tasks in ~StreamThread not working and thus the hang.

A simple fix is to just let the OS collect the threads, i.e. what this PR does. If you prefer a clean exit, we can have the language bindings destroy the Schedule in their exit handlers, which are called before the actual process exit.

@awni
Copy link
Member

awni commented Dec 31, 2024

but at least on Windows the destructors of static objects are called after the stream threads get terminated

You're saying StreamThread is deleted before Scheduler is deleted. Then in Scheduler destructor it tries to delete the StreamThread which joins on the thread and that causes a bug? What if we check thread.joinable in the destructor of StreamThread? Would it be false?

@zcbenz
Copy link
Contributor Author

zcbenz commented Dec 31, 2024

Yeah, the native OS thread got terminated on exit before the std::thread got destroyed. In my tests, once the main() function returns, all threads behaved like they received exit(0), and when using the win32 API to test their liveness, they were reported as exited.

    DWORD code = -1;
    GetExitCodeThread(thread.native_handle(), &code);
    fprintf(stderr, "exit code: %d\n", (int)code);

The thread.joinable() still returns true in this case, I think it is just a soft flag and does not check the actual status of the thread.

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.

2 participants