-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Disable thread support in libtest if RUST_TEST_THREADS=1
#107396
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @Mark-Simulacrum (or someone else) soon. Please see the contribution instructions for more information. |
Hey! It looks like you've submitted a new PR for the library teams! If this PR contains changes to any Examples of
|
0578b08
to
29b9547
Compare
r? @thomcc It feels like we might want this to be a separate knob, not related to threads=1... |
Agreed. Sometimes testing with N > 1 threads could also benefit from reusing threads instead of running a thread-per-test, e.g. when loads of thread-local caches or similar things need to be initialized. |
This kinda feels like a libs-api decision, regarding how this "should" work. |
Actually, I've realized that promising this and doing it in this manner would lock us into never fixing some bugs in libtest (like having no slow test notification on machines with 1 core). Let me dig up some old code and make a counter-proposal. |
As a vote in favour of the intent of this change (although I'm not following the details): I have a case where I need to test code that effectively locks future invocations of that same code to the same thread. This is to make internal use of global variables by the code sound. This is for an optional feature-based optimisation in the crate, but the optimisation is worthwhile for the cases where it is used, saving both memory and CPU. It tested fine until 1.67, but since then I can't test it because it immediately panics when it notices that it's running on another thread. Making RUST_TEST_THREADS=1 use just a single thread again would fix my problem. Right now I have to use a hacky workaround, using --list to get a list of tests and running them one by one. |
☔ The latest upstream changes (presumably #111992) made this pull request unmergeable. Please resolve the merge conflicts. |
Rust default test harness is very much unusable for anything on macOS that requires execution on main thread. Unfortunately main thread is special (so that on some places there are actually checks for |
FWIW running it all in one thread was also never intended to be a feature -- previous behavior (Rust 1.0 - ~1.30) was to always spawn threads; #56243 did the "run in a single thread" thing as a hack to make So, neither #56243 nor #103681 was intended to be more than an internal refactor, and neither should be read as indicating intent. Forcing a single thread has disadvantages (e.g. #59122). |
Something like this would be useful for us, as we found out yesterday during rust update. However seems other things also get broken by the previous behaviour which is a no-win situation. #[test(flavour = "static_thread")]
fn test_xyz() {} |
If the library has a requirement to run on a specific thread then it should do what many UI libraries do and provide something like Then tests that interact with that library can serialize themselves by dispatching to that thread. Other tests that don't touch that part can still run in parallel. None of that requires any changes to libtest. This is a problem of libraries that have additional requirements but do not provide the necessary facilities to meet those requirements in their API. |
It does require a change to free up the main thread for use by the ui framework. In many cases the ui thread can only be the main thread, but it is currently being used by libtest so nobody else can run anything on it. |
Yeah, apple provides those functions but a function you sent to that queue would never get run (and if you blocked on it, you'd deadlock), because libtest doesn't start the main loop. Overall I think this is something that should be discussed by t-testing. |
The API is all there - I can easily dispatch things to main thead on macOS (i.e. |
Last time (it has been a few years) I had to deal with these kinds of issues the framework had a way to initialize the UI event loop on something that was not the program's first/main thread.
Ok, I haven't dealt with macos. Does it not have that? |
Unfortunately no. There are hard-coded assumptions about main thread in various places. CFRunLoopRef CFRunLoopGetMain(void) {
CHECK_FOR_FORK();
static CFRunLoopRef __main = NULL; // no retain needed
if (!__main) __main = _CFRunLoopGet0(pthread_main_thread_np()); // no CAS needed
return __main;
} There are similar checks all over AppKit, libdispatch, etc. too. The only way for things to work properly is to keep running the run-loop ( |
I'm going to be away for a few months, so I'm rerolling my PRs so that folks don't have to wait for me. Sorry/thanks. r? libs |
I don't think we should make this behaviour implicit on RUST_TEST_THREADS=1. We might want another environment variable or a specical attribute to run a test on the main thread for example, but that's a design question separate from this PR, that will require an ACP and should probably be designed together with the testing team. @rfcbot close |
Team member @m-ou-se has proposed to close this. The next step is review by the rest of the tagged team members: No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
cc @rust-lang/testing-devex |
I agree with the disposition to close based on what I saw in the thread. Another workaround for this is to use a custom test harness ( |
After #103681, each test now runs in it's own thread if the platform supports it. This was true even if
RUST_TEST_THREADS=1
. Unfortunately, this causes some subtle breakage for certain libraries that may rely on thread-local storage being shared across tests (as is the case forlibruby
and Julia, and probably more).The feature never intended to cause any breakage, so restoring the previous behavior should be OK. I considered adding a new option, such as
RUST_TEST_THREADS=0
, which would allow both the new and previous behavior to exist side-by-side. But the idea of 0 threads felt... wrong. So I think this is the best way forward.This is my first rust PR, so please let me know if I missed anything! ❤️