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

Add OnceLock::wait #405

Closed
tgross35 opened this issue Jul 4, 2024 · 3 comments
Closed

Add OnceLock::wait #405

tgross35 opened this issue Jul 4, 2024 · 3 comments
Labels
ACP-accepted API Change Proposal is accepted (seconded with no objections) api-change-proposal A proposal to add or alter unstable APIs in the standard libraries T-libs-api

Comments

@tgross35
Copy link

tgross35 commented Jul 4, 2024

Proposal

Problem statement

OnceCell is useful for synchronizing write-once data, but it does not have any blocking methods that allow other threads to wait for this data.

Motivating examples or use cases

Sometimes it can be useful to allow the end of computation to return with a value across thread boundaries, when joining may not be acceptable. For example, rayon::spawn does not have a return value that allows for easy returning. Other applications are nested spawning, or cases where a worker thread should return a value (and unblock the parent thread) then continue going without joining.

The example from once_cell shows the basic structure:

use once_cell::sync::OnceCell;

let mut cell = std::sync::Arc::new(OnceCell::new());
let t = std::thread::spawn({
    let cell = std::sync::Arc::clone(&cell);
    move || cell.set(92).unwrap()
});

// Returns immediately, but might return None.
let _value_or_none = cell.get();

// Will return 92, but might block until the other thread does `.set`.
let value: &u32 = cell.wait();
assert_eq!(*value, 92);
t.join().unwrap();

Solution sketch

Add the following:

impl OnceLock {
    /// Block the current thread until the value is set, then return it
    fn wait(&self) -> &T;
}

Alternatives

Approximating this behavior with other synchronization primitives, e.g. Barrier to wait for the thread and Mutex to store the return value, or just manually parking (which this method is a thin wrapper around).

Links and related work

What happens now?

This issue contains an API change proposal (or ACP) and is part of the libs-api team feature lifecycle. Once this issue is filed, the libs-api team will review open proposals as capability becomes available. Current response times do not have a clear estimate, but may be up to several months.

Possible responses

The libs team may respond in various different ways. First, the team will consider the problem (this doesn't require any concrete solution or alternatives to have been proposed):

  • We think this problem seems worth solving, and the standard library might be the right place to solve it.
  • We think that this probably doesn't belong in the standard library.

Second, if there's a concrete solution:

  • We think this specific solution looks roughly right, approved, you or someone else should implement this. (Further review will still happen on the subsequent implementation PR.)
  • We're not sure this is the right solution, and the alternatives or other materials don't give us enough information to be sure about that. Here are some questions we have that aren't answered, or rough ideas about alternatives we'd want to see discussed.
@tgross35 tgross35 added api-change-proposal A proposal to add or alter unstable APIs in the standard libraries T-libs-api labels Jul 4, 2024
@tgross35
Copy link
Author

tgross35 commented Jul 4, 2024

Hm, the once_cell implementation does this by parking with a custom key https://github.com/matklad/once_cell/blob/c48d3c2c01de926228aea2ac1d03672b4ce160c1/src/imp_pl.rs#L80-L92 (cc @matklad). We don't currently have a way to block on Once, but maybe we could add one for internal use.

@matklad
Copy link
Member

matklad commented Jul 4, 2024

@tgross35 you probably want to look at the std impl, it should be closer to what std needs to do: https://github.com/matklad/once_cell/blob/c48d3c2c01de926228aea2ac1d03672b4ce160c1/src/imp_std.rs#L89

@m-ou-se
Copy link
Member

m-ou-se commented Jul 9, 2024

We discussed this in the libs-api meeting just now. We'd like to see this API added, and also on Once. We like the name wait, as it's very obvious what to wait for.

Feel free to open a tracking issue and open a PR to rust-lang/rust to add it as an unstable feature.

We did not discuss the potential implementation in detail.

It might be worth exploring what it would take to also have a .await'able version in the future.

@m-ou-se m-ou-se added the ACP-accepted API Change Proposal is accepted (seconded with no objections) label Jul 9, 2024
@m-ou-se m-ou-se closed this as completed Jul 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ACP-accepted API Change Proposal is accepted (seconded with no objections) api-change-proposal A proposal to add or alter unstable APIs in the standard libraries T-libs-api
Projects
None yet
Development

No branches or pull requests

3 participants