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::{
17 DoubleCheckedLockBuilder,
18 DoubleCheckedLockExecutor,
19};
20use qubit_lock::Lock;
21
22/// Entry type for one-shot double-checked lock execution.
23///
24/// This API is useful when you do not need to keep a reusable executor
25/// instance. It delegates to [`DoubleCheckedLockExecutor`] internally.
26///
27/// # Examples
28///
29/// ```rust
30/// use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
31///
32/// use qubit_dcl::{ArcMutex, DoubleCheckedLock, Lock};
33///
34/// let data = ArcMutex::new(10);
35/// let skip = Arc::new(AtomicBool::new(false));
36///
37/// let result = DoubleCheckedLock::on(data.clone())
38/// .when({
39/// let skip = skip.clone();
40/// move || !skip.load(Ordering::Acquire)
41/// })
42/// .call_with(|value: &mut i32| {
43/// *value += 5;
44/// Ok::<i32, std::io::Error>(*value)
45/// })
46/// .get_result();
47///
48/// assert!(result.is_success());
49/// assert_eq!(data.read(|value| *value), 15);
50/// ```
51#[derive(Debug, Clone, Copy, Default)]
52pub struct DoubleCheckedLock;
53
54impl DoubleCheckedLock {
55 /// Starts one-shot double-checked lock configuration by attaching a lock.
56 ///
57 /// # Parameters
58 ///
59 /// * `lock` - Lock handle protecting the data used by the one-shot
60 /// execution.
61 ///
62 /// # Returns
63 ///
64 /// A convenience builder that can configure the double-checked condition.
65 #[inline]
66 #[must_use = "assign or chain the returned builder"]
67 pub fn on<L, T>(lock: L) -> DoubleCheckedLockBuilder<L, T>
68 where
69 L: Lock<T>,
70 {
71 DoubleCheckedLockBuilder {
72 inner: DoubleCheckedLockExecutor::builder().on(lock),
73 }
74 }
75}