Skip to content

Make Proxy weak reference as it seems that it is not dropped at all - #165506

Draft
aerooneqq wants to merge 7 commits into
rust-lang:mainfrom
aerooneqq:count-external-tokens
Draft

aerooneqq wants to merge 7 commits into
rust-lang:mainfrom
aerooneqq:count-external-tokens

Conversation

@aerooneqq

@aerooneqq aerooneqq commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Trying to fix tests that fail when we enable two threads in frontend, this is a fix for a test failure when we did not return all tokens for job server. I tested it in top of #162848 with 2 and 222 threads and did not reproduce after 200 launches, while it was certainly reproducing after 20-30 launches without this fix.

There is a second failure which is an infinite hang that I managed to get one or two times locally (with 222 threads). I don't know the reason for it, but maybe this fix will also help as it did not reproduce with it.

cc @Kobzol @petrochenkov

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 5, 2026
@aerooneqq aerooneqq changed the title Don't rely on used when deciding whether to release a jobserver token Make Proxy weak reference as it seems that it is not dropped at all Nov 6, 2026
@aerooneqq
aerooneqq force-pushed the count-external-tokens branch from 387ff40 to 958a88e Compare November 6, 2026 10:05
@rustbot rustbot added A-compiletest Area: The compiletest test runner A-run-make Area: port run-make Makefiles to rmake.rs A-testsuite Area: The testsuite used to check the correctness of rustc T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-clippy Relevant to the Clippy team. labels Nov 6, 2026
@aerooneqq

Copy link
Copy Markdown
Contributor Author

@bors try jobs=test-x86_64-gnu-aux

@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Nov 6, 2026
Make `Proxy` weak reference as it seems that it is not dropped at all


try-job: test-x86_64-gnu-aux
@rust-bors

rust-bors Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

💔 Test for 23ce799 failed: CI. Failed job:

@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job test-x86_64-gnu-aux failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)

@petrochenkov petrochenkov self-assigned this Nov 6, 2026
@aerooneqq

aerooneqq commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor Author

To sum up the current state:

  • The first idea (the error in tokens calculation and the rewrite of it) didn't work locally as there is no error,
  • The second idea that Proxy is not dropped and something bad happens because of it fixed the issue with tokens locally, but it encounetered hang after ~300 launches of ./x t src/tools/cargo --stage 1 -- jobserver
  • Then I changed the command to ./x t src/tools/cargo --stage 1 -- jobserver --test-threads=1 and it survived 609 launches until I stopped it
  • In CI the failure now differs: locally I had only diff between tokens in test jobserver_and_j, here we have a failure of the code that is in https://github.com/rust-lang/cargo/blob/3c747ea3ead23951c1b43a5edfcbdb449135ddeb/tests/testsuite/jobserver.rs#L42, so it happened when this test code was executed, locally I haven't ever encountered this error:
    failures:
    2026-11-06T11:09:35.9053866Z 
    2026-11-06T11:09:35.9054359Z ---- jobserver::runner_inherits_jobserver stdout ----
    2026-11-06T11:09:35.9055125Z running `/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/cargo install --path .`
    2026-11-06T11:09:35.9055739Z running `make run -j2`
    2026-11-06T11:09:35.9055911Z 
    2026-11-06T11:09:35.9056303Z thread 'jobserver::runner_inherits_jobserver' (129959) panicked at src/tools/cargo/tests/testsuite/jobserver.rs:198:10:
    2026-11-06T11:09:35.9056783Z 
    2026-11-06T11:09:35.9056902Z test failed running `make run -j2`
    2026-11-06T11:09:35.9057405Z error: process exited with code 2 (expected 0)
    2026-11-06T11:09:35.9058050Z --- stdout
    2026-11-06T11:09:35.9058846Z make[1]: Entering directory '/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/tmp/cit/src/tools/cargo/testsuite/jobserver/runner_inherits_jobserver/foo'
    2026-11-06T11:09:35.9059895Z /checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/cargo run
    2026-11-06T11:09:35.9060953Z make[1]: Leaving directory '/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/tmp/cit/src/tools/cargo/testsuite/jobserver/runner_inherits_jobserver/foo'
    2026-11-06T11:09:35.9061905Z 
    2026-11-06T11:09:35.9062075Z --- stderr
    2026-11-06T11:09:35.9063481Z    Compiling cargo-jobserver-check v0.0.1 (/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/tmp/cit/src/tools/cargo/testsuite/jobserver/runner_inherits_jobserver/foo)
    2026-11-06T11:09:35.9065215Z     Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.38s
    2026-11-06T11:09:35.9065953Z      Running `target/debug/cargo-jobserver-check`
    2026-11-06T11:09:35.9066359Z 
    2026-11-06T11:09:35.9066612Z thread 'main' (130227) panicked at src/main.rs:26:44:
    2026-11-06T11:09:35.9067826Z called `Result::unwrap()` on an `Err` value: Os { code: 11, kind: WouldBlock, message: "Resource temporarily unavailable" }
    2026-11-06T11:09:35.9068962Z note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    2026-11-06T11:09:35.9069642Z make[1]: *** [Makefile:2: run] Error 101
    2026-11-06T11:09:35.9070281Z make[1]: INTERNAL: Exiting with 1 jobserver tokens available; should be 2!

If I understand correctly (I haven't debugged it yet) the cause of the missing token is not straight in the compiler but because we failed to write it back in main.

@petrochenkov petrochenkov added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Nov 6, 2026
helper: OnceLock::new(),
});
let proxy_ = Arc::clone(&proxy);
let weak_proxy = Arc::downgrade(&proxy);

@petrochenkov petrochenkov Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I agree that it's better to drop the Proxy rather than to leak it through an Arc cycle, but I'm still not sure what bad may happen if we don't do it (the only nontrivial piece of logic there is Drop for HelperThread).

View changes since the review

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think the helper thread could still have a token acquired but not yet dropped if a token was requested, but then rustc exits because of an error. By avoiding the arc cycle, the helper thread gets a chance to release the token before the process exits.

if let Ok(token) = token {
let mut data = proxy_.data.lock();
if let Ok(token) = token
&& let Some(proxy) = weak_proxy.upgrade()

@petrochenkov petrochenkov Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
&& let Some(proxy) = weak_proxy.upgrade()
&& let proxy = weak_proxy.upgrade().unwrap()

?
If we are here, then the helper thread is still running, and it means the Arc<Proxy> is not yet destroyed.

View changes since the review

@petrochenkov

Copy link
Copy Markdown
Contributor
            assert_eq!(read.read(&mut buf).unwrap(), 1);
            assert_eq!(write.write(&buf).unwrap(), 1);

WouldBlock during the write means that the pipe is full, but I'm not sure how it's possible if we just read from it.
Perhaps it makes sense to check first whether read and write actually refer to the same pipe.

@petrochenkov

Copy link
Copy Markdown
Contributor

(I think we can merge the Drop fix without blocking on investigation of the next jobserver::runner_inherits_jobserver failure.)

@petrochenkov petrochenkov removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 6, 2026
@petrochenkov petrochenkov added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Nov 6, 2026
@rust-bors

rust-bors Bot commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

☔ The latest upstream changes (presumably #165563) made this pull request unmergeable. Please resolve the merge conflicts by rebasing.

This branch has not been deployed

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

Labels

A-compiletest Area: The compiletest test runner A-run-make Area: port run-make Makefiles to rmake.rs A-testsuite Area: The testsuite used to check the correctness of rustc S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants