windows_future/
async_ready.rs

1use super::*;
2use std::sync::atomic::{AtomicBool, Ordering};
3
4struct ReadyState<T: Async> {
5    set_completed: AtomicBool,
6    result: Result<T::Output>,
7}
8
9impl<T: Async> ReadyState<T> {
10    fn new(result: Result<T::Output>) -> Self {
11        Self {
12            set_completed: AtomicBool::new(false),
13            result,
14        }
15    }
16
17    fn status(&self) -> AsyncStatus {
18        if self.result.is_ok() {
19            AsyncStatus::Completed
20        } else {
21            AsyncStatus::Error
22        }
23    }
24
25    // The "Ready" implementations don't need to store the handler since the handler is invoked immediately
26    // but still need to confirm that `SetCompleted` is called at most once.
27    fn invoke_completed(&self, sender: &T, handler: Ref<T::CompletedHandler>) -> Result<()> {
28        if !self.set_completed.swap(true, Ordering::SeqCst) {
29            sender.invoke_completed(handler.ok()?, self.status());
30            Ok(())
31        } else {
32            Err(Error::from_hresult(HRESULT(0x80000018u32 as i32))) // E_ILLEGAL_DELEGATE_ASSIGNMENT
33        }
34    }
35
36    // The `From` implementation is not used here since we don't want to transfer any error object to the calling thread.
37    // That happens when `GetResults` is called.
38    fn error_code(&self) -> HRESULT {
39        match &self.result {
40            Ok(_) => HRESULT(0),
41            Err(error) => error.code(),
42        }
43    }
44}
45
46#[implement(IAsyncAction, IAsyncInfo)]
47struct ReadyAction(ReadyState<IAsyncAction>);
48
49#[implement(IAsyncOperation<T>, IAsyncInfo)]
50struct ReadyOperation<T>(ReadyState<IAsyncOperation<T>>)
51where
52    T: RuntimeType + 'static;
53
54#[implement(IAsyncActionWithProgress<P>, IAsyncInfo)]
55struct ReadyActionWithProgress<P>(ReadyState<IAsyncActionWithProgress<P>>)
56where
57    P: RuntimeType + 'static;
58
59#[implement(IAsyncOperationWithProgress<T, P>, IAsyncInfo)]
60struct ReadyOperationWithProgress<T, P>(ReadyState<IAsyncOperationWithProgress<T, P>>)
61where
62    T: RuntimeType + 'static,
63    P: RuntimeType + 'static;
64
65impl IAsyncInfo_Impl for ReadyAction_Impl {
66    fn Id(&self) -> Result<u32> {
67        Ok(1)
68    }
69    fn Status(&self) -> Result<AsyncStatus> {
70        Ok(self.0.status())
71    }
72    fn ErrorCode(&self) -> Result<HRESULT> {
73        Ok(self.0.error_code())
74    }
75    fn Cancel(&self) -> Result<()> {
76        Ok(())
77    }
78    fn Close(&self) -> Result<()> {
79        Ok(())
80    }
81}
82
83impl<T: RuntimeType> IAsyncInfo_Impl for ReadyOperation_Impl<T> {
84    fn Id(&self) -> Result<u32> {
85        Ok(1)
86    }
87    fn Status(&self) -> Result<AsyncStatus> {
88        Ok(self.0.status())
89    }
90    fn ErrorCode(&self) -> Result<HRESULT> {
91        Ok(self.0.error_code())
92    }
93    fn Cancel(&self) -> Result<()> {
94        Ok(())
95    }
96    fn Close(&self) -> Result<()> {
97        Ok(())
98    }
99}
100
101impl<P: RuntimeType> IAsyncInfo_Impl for ReadyActionWithProgress_Impl<P> {
102    fn Id(&self) -> Result<u32> {
103        Ok(1)
104    }
105    fn Status(&self) -> Result<AsyncStatus> {
106        Ok(self.0.status())
107    }
108    fn ErrorCode(&self) -> Result<HRESULT> {
109        Ok(self.0.error_code())
110    }
111    fn Cancel(&self) -> Result<()> {
112        Ok(())
113    }
114    fn Close(&self) -> Result<()> {
115        Ok(())
116    }
117}
118
119impl<T: RuntimeType, P: RuntimeType> IAsyncInfo_Impl for ReadyOperationWithProgress_Impl<T, P> {
120    fn Id(&self) -> Result<u32> {
121        Ok(1)
122    }
123    fn Status(&self) -> Result<AsyncStatus> {
124        Ok(self.0.status())
125    }
126    fn ErrorCode(&self) -> Result<HRESULT> {
127        Ok(self.0.error_code())
128    }
129    fn Cancel(&self) -> Result<()> {
130        Ok(())
131    }
132    fn Close(&self) -> Result<()> {
133        Ok(())
134    }
135}
136
137impl IAsyncAction_Impl for ReadyAction_Impl {
138    fn SetCompleted(&self, handler: Ref<AsyncActionCompletedHandler>) -> Result<()> {
139        self.0.invoke_completed(&self.as_interface(), handler)
140    }
141    fn Completed(&self) -> Result<AsyncActionCompletedHandler> {
142        Err(Error::empty())
143    }
144    fn GetResults(&self) -> Result<()> {
145        self.0.result.clone()
146    }
147}
148
149impl<T: RuntimeType> IAsyncOperation_Impl<T> for ReadyOperation_Impl<T> {
150    fn SetCompleted(&self, handler: Ref<AsyncOperationCompletedHandler<T>>) -> Result<()> {
151        self.0.invoke_completed(&self.as_interface(), handler)
152    }
153    fn Completed(&self) -> Result<AsyncOperationCompletedHandler<T>> {
154        Err(Error::empty())
155    }
156    fn GetResults(&self) -> Result<T> {
157        self.0.result.clone()
158    }
159}
160
161impl<P: RuntimeType> IAsyncActionWithProgress_Impl<P> for ReadyActionWithProgress_Impl<P> {
162    fn SetCompleted(&self, handler: Ref<AsyncActionWithProgressCompletedHandler<P>>) -> Result<()> {
163        self.0.invoke_completed(&self.as_interface(), handler)
164    }
165    fn Completed(&self) -> Result<AsyncActionWithProgressCompletedHandler<P>> {
166        Err(Error::empty())
167    }
168    fn GetResults(&self) -> Result<()> {
169        self.0.result.clone()
170    }
171    fn SetProgress(&self, _: Ref<AsyncActionProgressHandler<P>>) -> Result<()> {
172        Ok(())
173    }
174    fn Progress(&self) -> Result<AsyncActionProgressHandler<P>> {
175        Err(Error::empty())
176    }
177}
178
179impl<T: RuntimeType, P: RuntimeType> IAsyncOperationWithProgress_Impl<T, P>
180    for ReadyOperationWithProgress_Impl<T, P>
181{
182    fn SetCompleted(
183        &self,
184        handler: Ref<AsyncOperationWithProgressCompletedHandler<T, P>>,
185    ) -> Result<()> {
186        self.0.invoke_completed(&self.as_interface(), handler)
187    }
188    fn Completed(&self) -> Result<AsyncOperationWithProgressCompletedHandler<T, P>> {
189        Err(Error::empty())
190    }
191    fn GetResults(&self) -> Result<T> {
192        self.0.result.clone()
193    }
194    fn SetProgress(&self, _: Ref<AsyncOperationProgressHandler<T, P>>) -> Result<()> {
195        Ok(())
196    }
197    fn Progress(&self) -> Result<AsyncOperationProgressHandler<T, P>> {
198        Err(Error::empty())
199    }
200}
201
202impl IAsyncAction {
203    /// Creates an `IAsyncAction` that is immediately ready with a value.
204    pub fn ready(result: Result<()>) -> Self {
205        ReadyAction(ReadyState::new(result)).into()
206    }
207}
208
209impl<T: RuntimeType> IAsyncOperation<T> {
210    /// Creates an `IAsyncOperation<T>` that is immediately ready with a value.
211    pub fn ready(result: Result<T>) -> Self {
212        ReadyOperation(ReadyState::new(result)).into()
213    }
214}
215
216impl<P: RuntimeType> IAsyncActionWithProgress<P> {
217    /// Creates an `IAsyncActionWithProgress<P>` that is immediately ready with a value.
218    pub fn ready(result: Result<()>) -> Self {
219        ReadyActionWithProgress(ReadyState::new(result)).into()
220    }
221}
222
223impl<T: RuntimeType, P: RuntimeType> IAsyncOperationWithProgress<T, P> {
224    /// Creates an `IAsyncOperationWithProgress<T, P>` that is immediately ready with a value.
225    pub fn ready(result: Result<T>) -> Self {
226        ReadyOperationWithProgress(ReadyState::new(result)).into()
227    }
228}