KEMBAR78
windows-threading: Implement `scope` for `Pool` by ChrisDenton · Pull Request #3696 · microsoft/windows-rs · GitHub
Skip to content

Conversation

@ChrisDenton
Copy link
Collaborator

@ChrisDenton ChrisDenton commented Aug 2, 2025

This is a fix #3695 that adds a scope API.

@ChrisDenton ChrisDenton changed the title Don't implement Send for windows_threading::Pool windows-threading: Implement scope for Pool Aug 3, 2025
@ChrisDenton
Copy link
Collaborator Author

Ok, looking at this more I do think we need a scope API to ensure this is robust so I've changed this PR to implement that,

While investigating this (and part of what drove this conclusion) I found that the service threading sample is not technically sound. Specifically these lines:

.run(|service, command| {
log(&format!("Command: {command:?}\n"));
match command {
Command::Start | Command::Resume => pool.submit(|| service_thread(service)),

service is a reference whose lifetime ends when the callback returns. However, here it's being sent to another thread which can potentially outlive the callback.

I think this requires changes in the service API to support either a reference counted Service object or else some other way to retrieve the Service from other threads.

@ChrisDenton ChrisDenton force-pushed the not-send branch 2 times, most recently from c627ff6 to 191d1b1 Compare August 3, 2025 19:04
Comment on lines +10 to +12
let service_original = Arc::new(RwLock::new(Service::new()));
let service = Arc::clone(&service_original);
service_original
Copy link
Collaborator

Choose a reason for hiding this comment

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

This seems overly complicated. The original Service::run terminated the process upon completion so that the run method was -> ! and the lifetime was much simpler. This was changed in #3662 to make it possible to test Service but perhaps that was a mistake.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Or the Service::run needs a similar scope pattern?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I wonder if it might be better (and simpler) to separate Service into two: one that constructs the service and another that accesses it afterward. The latter could then be freely moved, cloned, etc because it's just accessing global state (via appropriate locks).

Using the scoped pattern may be another option. I'm still not sure if that'd be more or less ergonomic though. It does need to be able to call the closure multiple times which complicates things. It might help if run consumed self rather than taking &mut self. I'd want to play about with this a bit more to see.

@kennykerr
Copy link
Collaborator

I definitely found a friction between Rust's lifetime model and the various restrictions in the threadpool APIs. I much prefer the addition of the scope API to restricting the pool to being single-threaded since the threadpool API itself is not single-threaded. I'll play around with this a bit but that seems like the right direction.

@kennykerr
Copy link
Collaborator

I played around with this today - I don't love how this impacts Service but that admittedly says more about Service than this change, which seems like the right thing to do and the service design can be improved separately.

@ChrisDenton
Copy link
Collaborator Author

I've been thinking a lot about the Service API and yeah, I don't love the workaround in this PR. It does need changes to the Service API itself but I'd be happy to leave that to follow up work.

@kennykerr kennykerr merged commit 50f140e into microsoft:master Aug 12, 2025
29 checks passed
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.

windows-threading lifetime soundness issue

2 participants