Skip to main content

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}