You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm wondering if it's worth implementing a get_mut_or_init. This method should accept a mutable reference so that it cannot be called concurrently.
A typical use case for modifying a mutable reference is calling get_or_init on an OnceCell whose value is something like Arc<Mutex<T>> so that it can be modified concurrently.
#[test]fnmulti_init_mut(){let rt = tokio::runtime::Builder::new_multi_thread().worker_threads(4).enable_time().build().unwrap();staticCELL:OnceCell<AtomicUsize> = OnceCell::new();
rt.block_on(async{constN:usize = 100;letmut handles = vec![];for i in0..N{
handles.push(rt.spawn(asyncmove{let result = CELL.get_or_init(move || asyncmove{AtomicUsize::new(1000 + i)}).await;
result.fetch_add(1,Ordering::Relaxed);
tokio::time::sleep(Duration::from_millis(100)).await;
result.load(Ordering::Relaxed)}));}letmut values = vec![];for handle in handles {
values.push(handle.await.unwrap());}let value = CELL.get().unwrap().load(Ordering::Relaxed);assert!(
value >= 1000 + N && value < 1000 + N + N,"final value: {}",
value
);for v in values {assert_eq!(v, value);}});}
While async primitives can be used to share cross threads, our OnceCell can be used as an analogy to std OnceLock while its pass-in function is an async fn.
Thus, this can be used as a cell that initialized only once and need not shared among threads.
Activity
BewareMyPower commentedon Nov 29, 2025
I'm wondering if it's worth implementing a
get_mut_or_init. This method should accept a mutable reference so that it cannot be called concurrently.A typical use case for modifying a mutable reference is calling
get_or_initon anOnceCellwhose value is something likeArc<Mutex<T>>so that it can be modified concurrently.tisonkun commentedon Nov 29, 2025
You can see the linked issue.
While async primitives can be used to share cross threads, our OnceCell can be used as an analogy to std OnceLock while its pass-in function is an async fn.
Thus, this can be used as a cell that initialized only once and need not shared among threads.
tisonkun commentedon Nov 29, 2025
See rust-lang/rust#74465 (comment)
BewareMyPower commentedon Nov 29, 2025
Okay, it makes sense