Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

169
vendor/windows-future/src/async.rs vendored Normal file
View File

@@ -0,0 +1,169 @@
use super::*;
// An `Async` represents a WinRT async execution object or type. There are precisely four such types:
// - IAsyncAction
// - IAsyncActionWithProgress
// - IAsyncOperation
// - IAsyncOperationWithProgress
//
// All four implementations are provided here and there is thus no need to implement this trait.
// This trait provides an abstraction over the relevant differences so that the various async
// capabilities in this crate can be reused for all implementations.
pub trait Async: Interface {
// The type of value produced on completion.
type Output: Clone;
// The type of the delegate use for completion notification.
type CompletedHandler: Interface;
// Sets the handler or callback to invoke when execution completes. This handler can only be set once.
fn set_completed<F: Fn(&Self) + Send + 'static>(&self, handler: F) -> Result<()>;
// Calls the given handler with the current object and status.
#[cfg(feature = "std")]
fn invoke_completed(&self, handler: &Self::CompletedHandler, status: AsyncStatus);
// Returns the value produced on completion. This should only be called when execution completes.
fn get_results(&self) -> Result<Self::Output>;
// Gets the current status of async execution. This calls `QueryInterface` so should be used sparingly.
fn status(&self) -> Result<AsyncStatus>;
// Waits for the async execution to finish and then returns the results.
fn join(&self) -> Result<Self::Output> {
if self.status()? == AsyncStatus::Started {
let (_waiter, signaler) = Waiter::new()?;
self.set_completed(move |_| {
// This is safe because the waiter will only be dropped after being signaled.
unsafe {
signaler.signal();
}
})?;
}
self.get_results()
}
// Calls `op(result)` when async execution completes.
fn when<F>(&self, op: F) -> Result<()>
where
F: FnOnce(Result<Self::Output>) + Send + 'static,
{
if self.status()? == AsyncStatus::Started {
// The `set_completed` closure is guaranteed to only be called once, like `FnOnce`, by the async pattern,
// but Rust doesn't know that so `RefCell` is used to pass `op` in to the closure.
let op = core::cell::RefCell::new(Some(op));
self.set_completed(move |sender| {
if let Some(op) = op.take() {
op(sender.get_results());
}
})?;
} else {
op(self.get_results());
}
Ok(())
}
}
impl Async for IAsyncAction {
type Output = ();
type CompletedHandler = AsyncActionCompletedHandler;
fn set_completed<F: Fn(&Self) + Send + 'static>(&self, handler: F) -> Result<()> {
self.SetCompleted(&AsyncActionCompletedHandler::new(move |sender, _| {
handler(sender.ok()?);
Ok(())
}))
}
#[cfg(feature = "std")]
fn invoke_completed(&self, handler: &Self::CompletedHandler, status: AsyncStatus) {
_ = handler.Invoke(self, status);
}
fn get_results(&self) -> Result<Self::Output> {
self.GetResults()
}
fn status(&self) -> Result<AsyncStatus> {
self.Status()
}
}
impl<T: RuntimeType> Async for IAsyncOperation<T> {
type Output = T;
type CompletedHandler = AsyncOperationCompletedHandler<T>;
fn set_completed<F: Fn(&Self) + Send + 'static>(&self, handler: F) -> Result<()> {
self.SetCompleted(&AsyncOperationCompletedHandler::new(move |sender, _| {
handler(sender.ok()?);
Ok(())
}))
}
#[cfg(feature = "std")]
fn invoke_completed(&self, handler: &Self::CompletedHandler, status: AsyncStatus) {
_ = handler.Invoke(self, status);
}
fn get_results(&self) -> Result<Self::Output> {
self.GetResults()
}
fn status(&self) -> Result<AsyncStatus> {
self.Status()
}
}
impl<P: RuntimeType> Async for IAsyncActionWithProgress<P> {
type Output = ();
type CompletedHandler = AsyncActionWithProgressCompletedHandler<P>;
fn set_completed<F: Fn(&Self) + Send + 'static>(&self, handler: F) -> Result<()> {
self.SetCompleted(&AsyncActionWithProgressCompletedHandler::new(
move |sender, _| {
handler(sender.ok()?);
Ok(())
},
))
}
#[cfg(feature = "std")]
fn invoke_completed(&self, handler: &Self::CompletedHandler, status: AsyncStatus) {
_ = handler.Invoke(self, status);
}
fn get_results(&self) -> Result<Self::Output> {
self.GetResults()
}
fn status(&self) -> Result<AsyncStatus> {
self.Status()
}
}
impl<T: RuntimeType, P: RuntimeType> Async for IAsyncOperationWithProgress<T, P> {
type Output = T;
type CompletedHandler = AsyncOperationWithProgressCompletedHandler<T, P>;
fn set_completed<F: Fn(&Self) + Send + 'static>(&self, handler: F) -> Result<()> {
self.SetCompleted(&AsyncOperationWithProgressCompletedHandler::new(
move |sender, _| {
handler(sender.ok()?);
Ok(())
},
))
}
#[cfg(feature = "std")]
fn invoke_completed(&self, handler: &Self::CompletedHandler, status: AsyncStatus) {
_ = handler.Invoke(self, status);
}
fn get_results(&self) -> Result<Self::Output> {
self.GetResults()
}
fn status(&self) -> Result<AsyncStatus> {
self.Status()
}
}

228
vendor/windows-future/src/async_ready.rs vendored Normal file
View File

@@ -0,0 +1,228 @@
use super::*;
use std::sync::atomic::{AtomicBool, Ordering};
struct ReadyState<T: Async> {
set_completed: AtomicBool,
result: Result<T::Output>,
}
impl<T: Async> ReadyState<T> {
fn new(result: Result<T::Output>) -> Self {
Self {
set_completed: AtomicBool::new(false),
result,
}
}
fn status(&self) -> AsyncStatus {
if self.result.is_ok() {
AsyncStatus::Completed
} else {
AsyncStatus::Error
}
}
// The "Ready" implementations don't need to store the handler since the handler is invoked immediately
// but still need to confirm that `SetCompleted` is called at most once.
fn invoke_completed(&self, sender: &T, handler: Ref<T::CompletedHandler>) -> Result<()> {
if !self.set_completed.swap(true, Ordering::SeqCst) {
sender.invoke_completed(handler.ok()?, self.status());
Ok(())
} else {
Err(Error::from_hresult(HRESULT(0x80000018u32 as i32))) // E_ILLEGAL_DELEGATE_ASSIGNMENT
}
}
// The `From` implementation is not used here since we don't want to transfer any error object to the calling thread.
// That happens when `GetResults` is called.
fn error_code(&self) -> HRESULT {
match &self.result {
Ok(_) => HRESULT(0),
Err(error) => error.code(),
}
}
}
#[implement(IAsyncAction, IAsyncInfo)]
struct ReadyAction(ReadyState<IAsyncAction>);
#[implement(IAsyncOperation<T>, IAsyncInfo)]
struct ReadyOperation<T>(ReadyState<IAsyncOperation<T>>)
where
T: RuntimeType + 'static;
#[implement(IAsyncActionWithProgress<P>, IAsyncInfo)]
struct ReadyActionWithProgress<P>(ReadyState<IAsyncActionWithProgress<P>>)
where
P: RuntimeType + 'static;
#[implement(IAsyncOperationWithProgress<T, P>, IAsyncInfo)]
struct ReadyOperationWithProgress<T, P>(ReadyState<IAsyncOperationWithProgress<T, P>>)
where
T: RuntimeType + 'static,
P: RuntimeType + 'static;
impl IAsyncInfo_Impl for ReadyAction_Impl {
fn Id(&self) -> Result<u32> {
Ok(1)
}
fn Status(&self) -> Result<AsyncStatus> {
Ok(self.0.status())
}
fn ErrorCode(&self) -> Result<HRESULT> {
Ok(self.0.error_code())
}
fn Cancel(&self) -> Result<()> {
Ok(())
}
fn Close(&self) -> Result<()> {
Ok(())
}
}
impl<T: RuntimeType> IAsyncInfo_Impl for ReadyOperation_Impl<T> {
fn Id(&self) -> Result<u32> {
Ok(1)
}
fn Status(&self) -> Result<AsyncStatus> {
Ok(self.0.status())
}
fn ErrorCode(&self) -> Result<HRESULT> {
Ok(self.0.error_code())
}
fn Cancel(&self) -> Result<()> {
Ok(())
}
fn Close(&self) -> Result<()> {
Ok(())
}
}
impl<P: RuntimeType> IAsyncInfo_Impl for ReadyActionWithProgress_Impl<P> {
fn Id(&self) -> Result<u32> {
Ok(1)
}
fn Status(&self) -> Result<AsyncStatus> {
Ok(self.0.status())
}
fn ErrorCode(&self) -> Result<HRESULT> {
Ok(self.0.error_code())
}
fn Cancel(&self) -> Result<()> {
Ok(())
}
fn Close(&self) -> Result<()> {
Ok(())
}
}
impl<T: RuntimeType, P: RuntimeType> IAsyncInfo_Impl for ReadyOperationWithProgress_Impl<T, P> {
fn Id(&self) -> Result<u32> {
Ok(1)
}
fn Status(&self) -> Result<AsyncStatus> {
Ok(self.0.status())
}
fn ErrorCode(&self) -> Result<HRESULT> {
Ok(self.0.error_code())
}
fn Cancel(&self) -> Result<()> {
Ok(())
}
fn Close(&self) -> Result<()> {
Ok(())
}
}
impl IAsyncAction_Impl for ReadyAction_Impl {
fn SetCompleted(&self, handler: Ref<AsyncActionCompletedHandler>) -> Result<()> {
self.0.invoke_completed(&self.as_interface(), handler)
}
fn Completed(&self) -> Result<AsyncActionCompletedHandler> {
Err(Error::empty())
}
fn GetResults(&self) -> Result<()> {
self.0.result.clone()
}
}
impl<T: RuntimeType> IAsyncOperation_Impl<T> for ReadyOperation_Impl<T> {
fn SetCompleted(&self, handler: Ref<AsyncOperationCompletedHandler<T>>) -> Result<()> {
self.0.invoke_completed(&self.as_interface(), handler)
}
fn Completed(&self) -> Result<AsyncOperationCompletedHandler<T>> {
Err(Error::empty())
}
fn GetResults(&self) -> Result<T> {
self.0.result.clone()
}
}
impl<P: RuntimeType> IAsyncActionWithProgress_Impl<P> for ReadyActionWithProgress_Impl<P> {
fn SetCompleted(&self, handler: Ref<AsyncActionWithProgressCompletedHandler<P>>) -> Result<()> {
self.0.invoke_completed(&self.as_interface(), handler)
}
fn Completed(&self) -> Result<AsyncActionWithProgressCompletedHandler<P>> {
Err(Error::empty())
}
fn GetResults(&self) -> Result<()> {
self.0.result.clone()
}
fn SetProgress(&self, _: Ref<AsyncActionProgressHandler<P>>) -> Result<()> {
Ok(())
}
fn Progress(&self) -> Result<AsyncActionProgressHandler<P>> {
Err(Error::empty())
}
}
impl<T: RuntimeType, P: RuntimeType> IAsyncOperationWithProgress_Impl<T, P>
for ReadyOperationWithProgress_Impl<T, P>
{
fn SetCompleted(
&self,
handler: Ref<AsyncOperationWithProgressCompletedHandler<T, P>>,
) -> Result<()> {
self.0.invoke_completed(&self.as_interface(), handler)
}
fn Completed(&self) -> Result<AsyncOperationWithProgressCompletedHandler<T, P>> {
Err(Error::empty())
}
fn GetResults(&self) -> Result<T> {
self.0.result.clone()
}
fn SetProgress(&self, _: Ref<AsyncOperationProgressHandler<T, P>>) -> Result<()> {
Ok(())
}
fn Progress(&self) -> Result<AsyncOperationProgressHandler<T, P>> {
Err(Error::empty())
}
}
impl IAsyncAction {
/// Creates an `IAsyncAction` that is immediately ready with a value.
pub fn ready(result: Result<()>) -> Self {
ReadyAction(ReadyState::new(result)).into()
}
}
impl<T: RuntimeType> IAsyncOperation<T> {
/// Creates an `IAsyncOperation<T>` that is immediately ready with a value.
pub fn ready(result: Result<T>) -> Self {
ReadyOperation(ReadyState::new(result)).into()
}
}
impl<P: RuntimeType> IAsyncActionWithProgress<P> {
/// Creates an `IAsyncActionWithProgress<P>` that is immediately ready with a value.
pub fn ready(result: Result<()>) -> Self {
ReadyActionWithProgress(ReadyState::new(result)).into()
}
}
impl<T: RuntimeType, P: RuntimeType> IAsyncOperationWithProgress<T, P> {
/// Creates an `IAsyncOperationWithProgress<T, P>` that is immediately ready with a value.
pub fn ready(result: Result<T>) -> Self {
ReadyOperationWithProgress(ReadyState::new(result)).into()
}
}

321
vendor/windows-future/src/async_spawn.rs vendored Normal file
View File

@@ -0,0 +1,321 @@
use super::*;
use std::sync::Mutex;
struct State<T: Async> {
result: Option<Result<T::Output>>,
completed: Option<T::CompletedHandler>,
completed_assigned: bool,
}
impl<T: Async> State<T> {
fn status(&self) -> AsyncStatus {
match &self.result {
None => AsyncStatus::Started,
Some(Ok(_)) => AsyncStatus::Completed,
Some(Err(_)) => AsyncStatus::Error,
}
}
fn error_code(&self) -> HRESULT {
match &self.result {
Some(Err(error)) => error.code(),
_ => HRESULT(0),
}
}
fn get_results(&self) -> Result<T::Output> {
match &self.result {
Some(result) => result.clone(),
None => Err(Error::from_hresult(HRESULT(0x8000000Eu32 as i32))), // E_ILLEGAL_METHOD_CALL
}
}
}
struct SyncState<T: Async>(Mutex<State<T>>);
impl<T: Async> SyncState<T> {
fn new() -> Self {
Self(Mutex::new(State {
result: None,
completed: None,
completed_assigned: false,
}))
}
fn status(&self) -> AsyncStatus {
self.0.lock().unwrap().status()
}
fn error_code(&self) -> HRESULT {
self.0.lock().unwrap().error_code()
}
fn get_results(&self) -> Result<T::Output> {
self.0.lock().unwrap().get_results()
}
fn set_completed(&self, sender: &T, handler: Ref<T::CompletedHandler>) -> Result<()> {
let mut guard = self.0.lock().unwrap();
if guard.completed_assigned {
Err(Error::from_hresult(HRESULT(0x80000018u32 as i32))) // E_ILLEGAL_DELEGATE_ASSIGNMENT
} else {
guard.completed_assigned = true;
let status = guard.status();
let handler = handler.ok()?;
if status == AsyncStatus::Started {
guard.completed = Some(handler.clone());
} else {
drop(guard);
sender.invoke_completed(handler, status);
}
Ok(())
}
}
fn spawn<F>(&self, sender: &T, f: F)
where
F: FnOnce() -> Result<T::Output> + Send + 'static,
{
let result = f();
let mut guard = self.0.lock().unwrap();
debug_assert!(guard.result.is_none());
guard.result = Some(result);
let status = guard.status();
let completed = guard.completed.take();
drop(guard);
if let Some(completed) = completed {
sender.invoke_completed(&completed, status);
}
}
}
unsafe impl<T: Async> Send for SyncState<T> {}
#[implement(IAsyncAction, IAsyncInfo)]
struct Action(SyncState<IAsyncAction>);
#[implement(IAsyncOperation<T>, IAsyncInfo)]
struct Operation<T>(SyncState<IAsyncOperation<T>>)
where
T: RuntimeType + 'static;
#[implement(IAsyncActionWithProgress<P>, IAsyncInfo)]
struct ActionWithProgress<P>(SyncState<IAsyncActionWithProgress<P>>)
where
P: RuntimeType + 'static;
#[implement(IAsyncOperationWithProgress<T, P>, IAsyncInfo)]
struct OperationWithProgress<T, P>(SyncState<IAsyncOperationWithProgress<T, P>>)
where
T: RuntimeType + 'static,
P: RuntimeType + 'static;
impl IAsyncInfo_Impl for Action_Impl {
fn Id(&self) -> Result<u32> {
Ok(1)
}
fn Status(&self) -> Result<AsyncStatus> {
Ok(self.0.status())
}
fn ErrorCode(&self) -> Result<HRESULT> {
Ok(self.0.error_code())
}
fn Cancel(&self) -> Result<()> {
Ok(())
}
fn Close(&self) -> Result<()> {
Ok(())
}
}
impl<T: RuntimeType> IAsyncInfo_Impl for Operation_Impl<T> {
fn Id(&self) -> Result<u32> {
Ok(1)
}
fn Status(&self) -> Result<AsyncStatus> {
Ok(self.0.status())
}
fn ErrorCode(&self) -> Result<HRESULT> {
Ok(self.0.error_code())
}
fn Cancel(&self) -> Result<()> {
Ok(())
}
fn Close(&self) -> Result<()> {
Ok(())
}
}
impl<P: RuntimeType> IAsyncInfo_Impl for ActionWithProgress_Impl<P> {
fn Id(&self) -> Result<u32> {
Ok(1)
}
fn Status(&self) -> Result<AsyncStatus> {
Ok(self.0.status())
}
fn ErrorCode(&self) -> Result<HRESULT> {
Ok(self.0.error_code())
}
fn Cancel(&self) -> Result<()> {
Ok(())
}
fn Close(&self) -> Result<()> {
Ok(())
}
}
impl<T: RuntimeType, P: RuntimeType> IAsyncInfo_Impl for OperationWithProgress_Impl<T, P> {
fn Id(&self) -> Result<u32> {
Ok(1)
}
fn Status(&self) -> Result<AsyncStatus> {
Ok(self.0.status())
}
fn ErrorCode(&self) -> Result<HRESULT> {
Ok(self.0.error_code())
}
fn Cancel(&self) -> Result<()> {
Ok(())
}
fn Close(&self) -> Result<()> {
Ok(())
}
}
impl IAsyncAction_Impl for Action_Impl {
fn SetCompleted(&self, handler: Ref<AsyncActionCompletedHandler>) -> Result<()> {
self.0.set_completed(&self.as_interface(), handler)
}
fn Completed(&self) -> Result<AsyncActionCompletedHandler> {
Err(Error::empty())
}
fn GetResults(&self) -> Result<()> {
self.0.get_results()
}
}
impl<T: RuntimeType> IAsyncOperation_Impl<T> for Operation_Impl<T> {
fn SetCompleted(&self, handler: Ref<AsyncOperationCompletedHandler<T>>) -> Result<()> {
self.0.set_completed(&self.as_interface(), handler)
}
fn Completed(&self) -> Result<AsyncOperationCompletedHandler<T>> {
Err(Error::empty())
}
fn GetResults(&self) -> Result<T> {
self.0.get_results()
}
}
impl<P: RuntimeType> IAsyncActionWithProgress_Impl<P> for ActionWithProgress_Impl<P> {
fn SetCompleted(&self, handler: Ref<AsyncActionWithProgressCompletedHandler<P>>) -> Result<()> {
self.0.set_completed(&self.as_interface(), handler)
}
fn Completed(&self) -> Result<AsyncActionWithProgressCompletedHandler<P>> {
Err(Error::empty())
}
fn GetResults(&self) -> Result<()> {
self.0.get_results()
}
fn SetProgress(&self, _: Ref<AsyncActionProgressHandler<P>>) -> Result<()> {
Ok(())
}
fn Progress(&self) -> Result<AsyncActionProgressHandler<P>> {
Err(Error::empty())
}
}
impl<T: RuntimeType, P: RuntimeType> IAsyncOperationWithProgress_Impl<T, P>
for OperationWithProgress_Impl<T, P>
{
fn SetCompleted(
&self,
handler: Ref<AsyncOperationWithProgressCompletedHandler<T, P>>,
) -> Result<()> {
self.0.set_completed(&self.as_interface(), handler)
}
fn Completed(&self) -> Result<AsyncOperationWithProgressCompletedHandler<T, P>> {
Err(Error::empty())
}
fn GetResults(&self) -> Result<T> {
self.0.get_results()
}
fn SetProgress(&self, _: Ref<AsyncOperationProgressHandler<T, P>>) -> Result<()> {
Ok(())
}
fn Progress(&self) -> Result<AsyncOperationProgressHandler<T, P>> {
Err(Error::empty())
}
}
impl IAsyncAction {
/// Creates an `IAsyncAction` that waits for the closure to execute on the Windows thread pool.
pub fn spawn<F>(f: F) -> Self
where
F: FnOnce() -> Result<()> + Send + 'static,
{
let object = ComObject::new(Action(SyncState::new()));
let interface = object.to_interface();
windows_threading::submit(move || {
object.0.spawn(&object.as_interface(), f);
});
interface
}
}
impl<T: RuntimeType> IAsyncOperation<T> {
/// Creates an `IAsyncOperation<T>` that waits for the closure to execute on the Windows thread pool.
pub fn spawn<F>(f: F) -> Self
where
F: FnOnce() -> Result<T> + Send + 'static,
{
let object = ComObject::new(Operation(SyncState::new()));
let interface = object.to_interface();
windows_threading::submit(move || {
object.0.spawn(&object.as_interface(), f);
});
interface
}
}
impl<P: RuntimeType> IAsyncActionWithProgress<P> {
/// Creates an `IAsyncActionWithProgress<P>` that waits for the closure to execute on the Windows thread pool.
pub fn spawn<F>(f: F) -> Self
where
F: FnOnce() -> Result<()> + Send + 'static,
{
let object = ComObject::new(ActionWithProgress(SyncState::new()));
let interface = object.to_interface();
windows_threading::submit(move || {
object.0.spawn(&object.as_interface(), f);
});
interface
}
}
impl<T: RuntimeType, P: RuntimeType> IAsyncOperationWithProgress<T, P> {
/// Creates an `IAsyncOperationWithProgress<T, P>` that waits for the closure to execute on the Windows thread pool.
pub fn spawn<F>(f: F) -> Self
where
F: FnOnce() -> Result<T> + Send + 'static,
{
let object = ComObject::new(OperationWithProgress(SyncState::new()));
let interface = object.to_interface();
windows_threading::submit(move || {
object.0.spawn(&object.as_interface(), f);
});
interface
}
}

2235
vendor/windows-future/src/bindings.rs vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,20 @@
windows_link::link!("kernel32.dll" "system" fn CloseHandle(hobject : HANDLE) -> BOOL);
windows_link::link!("kernel32.dll" "system" fn CreateEventW(lpeventattributes : *const SECURITY_ATTRIBUTES, bmanualreset : BOOL, binitialstate : BOOL, lpname : PCWSTR) -> HANDLE);
windows_link::link!("kernel32.dll" "system" fn SetEvent(hevent : HANDLE) -> BOOL);
windows_link::link!("kernel32.dll" "system" fn WaitForSingleObject(hhandle : HANDLE, dwmilliseconds : u32) -> WAIT_EVENT);
pub type BOOL = i32;
pub type HANDLE = *mut core::ffi::c_void;
pub type PCWSTR = *const u16;
#[repr(C)]
#[derive(Clone, Copy)]
pub struct SECURITY_ATTRIBUTES {
pub nLength: u32,
pub lpSecurityDescriptor: *mut core::ffi::c_void,
pub bInheritHandle: BOOL,
}
impl Default for SECURITY_ATTRIBUTES {
fn default() -> Self {
unsafe { core::mem::zeroed() }
}
}
pub type WAIT_EVENT = u32;

121
vendor/windows-future/src/future.rs vendored Normal file
View File

@@ -0,0 +1,121 @@
use super::*;
use std::future::{Future, IntoFuture};
use std::pin::Pin;
use std::sync::{Arc, Mutex};
use std::task::{Context, Poll, Waker};
// The `AsyncFuture` is needed to store some extra state needed to keep async execution up to date with possible changes
// to Rust execution context. Each async type implements `IntoFuture` rather than implementing `Future` directly so that
// this adapter may be used.
pub struct AsyncFuture<A: Async> {
// Represents the async execution and provides the virtual methods for setting up a `Completed` handler and
// calling `GetResults` when execution is completed.
inner: A,
// Provides the `Status` virtual method and saves repeated calls to `QueryInterface` during polling.
status: IAsyncInfo,
// A shared waker is needed to keep the `Completed` handler updated.
// - `Option` is used to avoid allocations for async objects that have already completed.
// - `Arc` is used to share the `Waker` with the `Completed` handler and potentially replace the `Waker`
// since we don't have the ability to replace the `Completed` handler itself.
// - `Mutex` is used to synchronize replacing the `Waker` across threads.
waker: Option<Arc<Mutex<Waker>>>,
}
impl<A: Async> AsyncFuture<A> {
fn new(inner: A) -> Self {
Self {
// All four async interfaces implement `IAsyncInfo` so this `cast` will always succeed.
status: inner.cast().unwrap(),
inner,
waker: None,
}
}
}
unsafe impl<A: Async> Send for AsyncFuture<A> {}
unsafe impl<A: Async> Sync for AsyncFuture<A> {}
impl<A: Async> Unpin for AsyncFuture<A> {}
impl<A: Async> Future for AsyncFuture<A> {
type Output = Result<A::Output>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
// A status of `Started` just means async execution is still in flight. Since WinRT async is always
// "hot start", if its not `Started` then its ready for us to call `GetResults` so we can skip all of
// the remaining set up.
if self.status.Status()? != AsyncStatus::Started {
return Poll::Ready(self.inner.get_results());
}
if let Some(shared_waker) = &self.waker {
// We have a shared waker which means we're either getting polled again or been transferred to
// another execution context. As we can't tell the difference, we need to update the shared waker
// to make sure we've got the "current" waker.
let mut guard = shared_waker.lock().unwrap();
guard.clone_from(cx.waker());
// It may be possible that the `Completed` handler acquired the lock and signaled the old waker
// before we managed to acquire the lock to update it with the current waker. We check the status
// again here just in case this happens.
if self.status.Status()? != AsyncStatus::Started {
return Poll::Ready(self.inner.get_results());
}
} else {
// If we don't have a saved waker it means this is the first time we're getting polled and should
// create the shared waker and set up a `Completed` handler.
let shared_waker = Arc::new(Mutex::new(cx.waker().clone()));
self.waker = Some(shared_waker.clone());
// Note that the handler can only be set once, which is why we need a shared waker in the first
// place. On the other hand, the handler will get called even if async execution has already
// completed, so we can just return `Pending` after setting the Completed handler.
self.inner.set_completed(move |_| {
shared_waker.lock().unwrap().wake_by_ref();
})?;
};
Poll::Pending
}
}
//
// The four `IntoFuture` trait implementations.
//
impl IntoFuture for IAsyncAction {
type Output = Result<()>;
type IntoFuture = AsyncFuture<Self>;
fn into_future(self) -> Self::IntoFuture {
AsyncFuture::new(self)
}
}
impl<T: RuntimeType> IntoFuture for IAsyncOperation<T> {
type Output = Result<T>;
type IntoFuture = AsyncFuture<Self>;
fn into_future(self) -> Self::IntoFuture {
AsyncFuture::new(self)
}
}
impl<P: RuntimeType> IntoFuture for IAsyncActionWithProgress<P> {
type Output = Result<()>;
type IntoFuture = AsyncFuture<Self>;
fn into_future(self) -> Self::IntoFuture {
AsyncFuture::new(self)
}
}
impl<T: RuntimeType, P: RuntimeType> IntoFuture for IAsyncOperationWithProgress<T, P> {
type Output = Result<T>;
type IntoFuture = AsyncFuture<Self>;
fn into_future(self) -> Self::IntoFuture {
AsyncFuture::new(self)
}
}

29
vendor/windows-future/src/join.rs vendored Normal file
View File

@@ -0,0 +1,29 @@
use super::*;
impl IAsyncAction {
/// Waits for the `IAsyncAction` to finish.
pub fn join(&self) -> Result<()> {
Async::join(self)
}
}
impl<T: RuntimeType> IAsyncOperation<T> {
/// Waits for the `IAsyncOperation<T>` to finish.
pub fn join(&self) -> Result<T> {
Async::join(self)
}
}
impl<P: RuntimeType> IAsyncActionWithProgress<P> {
/// Waits for the `IAsyncActionWithProgress<P>` to finish.
pub fn join(&self) -> Result<()> {
Async::join(self)
}
}
impl<T: RuntimeType, P: RuntimeType> IAsyncOperationWithProgress<T, P> {
/// Waits for the `IAsyncOperationWithProgress<T, P>` to finish.
pub fn join(&self) -> Result<T> {
Async::join(self)
}
}

29
vendor/windows-future/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,29 @@
#![expect(
missing_docs,
non_snake_case,
non_camel_case_types,
non_upper_case_globals,
clippy::all
)]
#![doc = include_str!("../readme.md")]
#![cfg_attr(all(not(feature = "std")), no_std)]
mod r#async;
mod bindings;
mod bindings_impl;
mod join;
mod waiter;
mod when;
pub use bindings::*;
use bindings_impl::*;
use r#async::*;
use waiter::*;
use windows_core::*;
#[cfg(feature = "std")]
mod async_ready;
#[cfg(feature = "std")]
mod async_spawn;
#[cfg(feature = "std")]
mod future;

41
vendor/windows-future/src/waiter.rs vendored Normal file
View File

@@ -0,0 +1,41 @@
use super::*;
pub struct Waiter(HANDLE);
pub struct WaiterSignaler(HANDLE);
unsafe impl Send for WaiterSignaler {}
impl Waiter {
pub fn new() -> crate::Result<(Self, WaiterSignaler)> {
unsafe {
let handle = CreateEventW(core::ptr::null(), 1, 0, core::ptr::null());
if handle.is_null() {
Err(crate::Error::from_thread())
} else {
Ok((Self(handle), WaiterSignaler(handle)))
}
}
}
}
impl WaiterSignaler {
/// # Safety
/// Signals the `Waiter`. This is unsafe because the lifetime of `WaiterSignaler` is not tied
/// to the lifetime of the `Waiter`. This is not possible in this case because the `Waiter`
/// is used to signal a WinRT async completion and the compiler doesn't know that the lifetime
/// of the delegate is bounded by the calling function.
pub unsafe fn signal(&self) {
// https://github.com/microsoft/windows-rs/pull/374#discussion_r535313344
unsafe {
SetEvent(self.0);
}
}
}
impl Drop for Waiter {
fn drop(&mut self) {
unsafe {
WaitForSingleObject(self.0, 0xFFFFFFFF);
CloseHandle(self.0);
}
}
}

41
vendor/windows-future/src/when.rs vendored Normal file
View File

@@ -0,0 +1,41 @@
use super::*;
impl IAsyncAction {
/// Calls `op(result)` when the `IAsyncAction` completes.
pub fn when<F>(&self, op: F) -> Result<()>
where
F: FnOnce(Result<()>) + Send + 'static,
{
Async::when(self, op)
}
}
impl<T: RuntimeType> IAsyncOperation<T> {
/// Calls `op(result)` when the `IAsyncOperation<T>` completes.
pub fn when<F>(&self, op: F) -> Result<()>
where
F: FnOnce(Result<T>) + Send + 'static,
{
Async::when(self, op)
}
}
impl<P: RuntimeType> IAsyncActionWithProgress<P> {
/// Calls `op(result)` when the `IAsyncActionWithProgress<P>` completes.
pub fn when<F>(&self, op: F) -> Result<()>
where
F: FnOnce(Result<()>) + Send + 'static,
{
Async::when(self, op)
}
}
impl<T: RuntimeType, P: RuntimeType> IAsyncOperationWithProgress<T, P> {
/// Calls `op(result)` when the `IAsyncOperationWithProgress<T, P>` completes.
pub fn when<F>(&self, op: F) -> Result<()>
where
F: FnOnce(Result<T>) + Send + 'static,
{
Async::when(self, op)
}
}