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}