Skip to main content

qubit_executor/task/
task_completion_pair.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 ******************************************************************************/
10use std::sync::Arc;
11
12use qubit_atomic::Atomic;
13use qubit_lock::Monitor;
14
15use super::task_completion::TaskCompletion;
16use super::task_handle::TaskHandle;
17use super::task_handle_inner::TaskHandleInner;
18use super::task_handle_state::TaskHandleState;
19
20/// One-shot pair of endpoints for an accepted task.
21///
22/// A pair owns the shared task state until it is split into a caller-facing
23/// [`TaskHandle`] and a runner-facing [`TaskCompletion`].
24pub struct TaskCompletionPair<R, E> {
25    /// Shared state consumed when the pair is split.
26    inner: Arc<TaskHandleInner<R, E>>,
27}
28
29impl<R, E> TaskCompletionPair<R, E> {
30    /// Creates a new unsplit task completion pair.
31    ///
32    /// # Returns
33    ///
34    /// A pair that can be split once into its handle and completion endpoints.
35    #[inline]
36    pub fn new() -> Self {
37        Self {
38            inner: Arc::new(TaskHandleInner {
39                state: Monitor::new(TaskHandleState {
40                    result: None,
41                    started: false,
42                    completed: false,
43                    waker: None,
44                }),
45                done: Atomic::new(false),
46            }),
47        }
48    }
49
50    /// Splits this pair into caller and runner endpoints.
51    ///
52    /// # Returns
53    ///
54    /// A [`TaskHandle`] for the caller and a [`TaskCompletion`] for the runner.
55    #[inline]
56    pub fn into_parts(self) -> (TaskHandle<R, E>, TaskCompletion<R, E>) {
57        let handle = TaskHandle {
58            inner: Arc::clone(&self.inner),
59        };
60        let completion = TaskCompletion { inner: self.inner };
61        (handle, completion)
62    }
63}
64
65impl<R, E> Default for TaskCompletionPair<R, E> {
66    /// Creates a new unsplit task completion pair.
67    #[inline]
68    fn default() -> Self {
69        Self::new()
70    }
71}