Skip to content

Commit e85924c

Browse files
committed
Cleanup
1 parent c0837e6 commit e85924c

File tree

2 files changed

+66
-52
lines changed

2 files changed

+66
-52
lines changed

examples/async.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ async fn run() {
4747
// println!("status: {:?}", status);
4848

4949
let mut interval = Interval::new(Duration::from_millis(100));
50-
let mut async_op = DeviceInformation::find_all_async().unwrap().fuse(); // TODO: get rid of fuse()
50+
let mut async_op = DeviceInformation::find_all_async().unwrap().fuse();
5151

5252
let work = async {
5353
let mut result = None;

src/rt/async_util.rs

Lines changed: 65 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use futures::future::Future;
22
use std::pin::Pin;
3+
use std::ops::Deref;
34
use std::task::{Context, Poll};
45
use std::sync::{Arc, Mutex, Condvar};
56

@@ -78,8 +79,7 @@ macro_rules! impl_blocking_wait {
7879
}
7980
}
8081

81-
impl RtAsyncAction for IAsyncAction
82-
{
82+
impl RtAsyncAction for IAsyncAction {
8383
impl_blocking_wait!{ AsyncActionCompletedHandler }
8484
}
8585

@@ -95,39 +95,6 @@ impl<T: RtType + 'static> RtAsyncAction for IAsyncOperation<T>
9595
impl_blocking_wait!{ AsyncOperationCompletedHandler }
9696
}
9797

98-
impl<'a, T: RtType + 'static> Future for crate::ComPtr<IAsyncOperation<T>>
99-
where AsyncOperationCompletedHandler<T>: ComIid
100-
{
101-
type Output = Result<<T as RtType>::Out>;
102-
103-
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
104-
use std::ops::Deref;
105-
106-
let info = crate::comptr::query_interface::<_, IAsyncInfo>(self.deref().deref()).expect("query_interface failed");
107-
let status = info.get_status().expect("get_status failed");
108-
match status {
109-
crate::langcompat::ASYNC_STATUS_COMPLETED => {
110-
Poll::Ready(self.get_results())
111-
},
112-
crate::langcompat::ASYNC_STATUS_STARTED => {
113-
if self.get_completed().expect("get_completed failed").is_some() {
114-
return Poll::Pending;
115-
}
116-
let waker = cx.waker().clone();
117-
118-
let handler = AsyncOperationCompletedHandler::new(move |_op, _status| {
119-
waker.wake_by_ref();
120-
Ok(())
121-
});
122-
123-
self.set_completed(&handler).expect("set_completed failed");
124-
Poll::Pending
125-
}
126-
_ => unimplemented!()
127-
}
128-
}
129-
}
130-
13198
impl<T: RtType + 'static> RtAsyncOperation for IAsyncOperation<T>
13299
where AsyncOperationCompletedHandler<T>: ComIid
133100
{
@@ -156,20 +123,67 @@ impl<T: RtType + 'static, P: RtType + 'static> RtAsyncOperation for IAsyncOperat
156123
}
157124
}
158125

159-
// Make await syntax work with `ComPtr` directly
160-
/*impl<'a, T: RtType + 'static> Future for &'a crate::ComPtr<T>
161-
where &'a T: Future,
162-
//&'a crate::rt::gen::windows::foundation::IAsyncOperation<T> : futures::Future,
163-
//&'a crate::ComPtr<T>: Unpin
164-
{
165-
type Output = <&'a T as Future>::Output;
166-
#[inline] fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
167-
use std::ops::DerefMut;
168-
//unsafe { self.map_unchecked(|ptr| ptr.deref().deref()) }.poll(self, cx)
169-
let s: Pin<&mut &_>/*: Pin<&mut &IAsyncOperation<_>>*/ = unsafe { self.map_unchecked_mut(|mut ptr| &mut&**ptr) };
170-
//let s: Pin<&mut &'a IAsyncOperation<T>> = Pin::new(&mut **self.get_mut().deref_mut().deref_mut());
171-
//let p: crate::ComPtr<T>
172-
s.poll(cx)
173-
//unimplemented!()
126+
127+
macro_rules! impl_poll {
128+
($handler:ident => $retexpr:tt) => {
129+
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
130+
let info = crate::comptr::query_interface::<_, IAsyncInfo>(self.deref().deref()).expect("query_interface failed");
131+
let status = info.get_status().expect("get_status failed");
132+
match status {
133+
crate::windows::foundation::AsyncStatus::Completed => {
134+
Poll::Ready($retexpr(self))
135+
},
136+
crate::windows::foundation::AsyncStatus::Started => {
137+
// Calling poll multiple times must work correctly, so we have to check that we didn't already install the Completed handler
138+
if self.get_completed().expect("get_completed failed").is_some() {
139+
// TODO: We might have to check that the installed handler is actually
140+
// the one with the waker (because the user could have installed one independently).
141+
// Or we document that the user is not allowed to do that.
142+
return Poll::Pending;
143+
}
144+
let waker = cx.waker().clone();
145+
146+
let handler = $handler::new(move |_op, _status| {
147+
waker.wake_by_ref();
148+
Ok(())
149+
});
150+
151+
self.set_completed(&handler).expect("set_completed failed");
152+
Poll::Pending
153+
}
154+
_ => unimplemented!() // FIXME
155+
}
156+
}
174157
}
175-
}*/
158+
}
159+
160+
161+
impl Future for crate::ComPtr<IAsyncAction> {
162+
type Output = ();
163+
164+
impl_poll!{ AsyncActionCompletedHandler => { |_: Pin<&mut Self>| () } }
165+
}
166+
167+
impl<P: RtType + 'static> Future for crate::ComPtr<IAsyncActionWithProgress<P>>
168+
where AsyncActionWithProgressCompletedHandler<P>: ComIid
169+
{
170+
type Output = ();
171+
172+
impl_poll!{ AsyncActionWithProgressCompletedHandler => { |_: Pin<&mut Self>| () } }
173+
}
174+
175+
impl<T: RtType + 'static> Future for crate::ComPtr<IAsyncOperation<T>>
176+
where AsyncOperationCompletedHandler<T>: ComIid
177+
{
178+
type Output = Result<<T as RtType>::Out>;
179+
180+
impl_poll!{ AsyncOperationCompletedHandler => { |s: Pin<&mut Self>| s.get_results() } }
181+
}
182+
183+
impl<T: RtType + 'static, P: RtType + 'static> Future for crate::ComPtr<IAsyncOperationWithProgress<T, P>>
184+
where AsyncOperationWithProgressCompletedHandler<T, P>: ComIid
185+
{
186+
type Output = Result<<T as RtType>::Out>;
187+
188+
impl_poll!{ AsyncOperationWithProgressCompletedHandler => { |s: Pin<&mut Self>| s.get_results() } }
189+
}

0 commit comments

Comments
 (0)