qubit_dcl/double_checked/double_checked_lock.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025 - 2026 Haixing Hu.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10//! # Double-Checked Lock Convenience API
11//!
12//! Provides a one-shot convenience wrapper around
13//! [`super::DoubleCheckedLockExecutor`].
14//!
15
16use super::{DoubleCheckedLockBuilder, DoubleCheckedLockExecutor};
17use crate::lock::Lock;
18
19/// Entry type for one-shot double-checked lock execution.
20///
21/// This API is useful when you do not need to keep a reusable executor
22/// instance. It delegates to [`DoubleCheckedLockExecutor`] internally.
23///
24/// # Examples
25///
26/// ```rust
27/// use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
28///
29/// use qubit_dcl::{ArcMutex, DoubleCheckedLock, Lock};
30///
31/// let data = ArcMutex::new(10);
32/// let skip = Arc::new(AtomicBool::new(false));
33///
34/// let result = DoubleCheckedLock::on(data.clone())
35/// .when({
36/// let skip = skip.clone();
37/// move || !skip.load(Ordering::Acquire)
38/// })
39/// .call_with(|value: &mut i32| {
40/// *value += 5;
41/// Ok::<i32, std::io::Error>(*value)
42/// })
43/// .get_result();
44///
45/// assert!(result.is_success());
46/// assert_eq!(data.read(|value| *value), 15);
47/// ```
48#[derive(Debug, Clone, Copy, Default)]
49pub struct DoubleCheckedLock;
50
51impl DoubleCheckedLock {
52 /// Starts one-shot double-checked lock configuration by attaching a lock.
53 #[inline]
54 pub fn on<L, T>(lock: L) -> DoubleCheckedLockBuilder<L, T>
55 where
56 L: Lock<T>,
57 {
58 DoubleCheckedLockBuilder {
59 inner: DoubleCheckedLockExecutor::builder().on(lock),
60 }
61 }
62}