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