Skip to content

Commit

Permalink
Add async spawn support (#3235)
Browse files Browse the repository at this point in the history
  • Loading branch information
kennykerr authored Aug 31, 2024
1 parent 2f94f90 commit ef06753
Show file tree
Hide file tree
Showing 24 changed files with 1,302 additions and 308 deletions.
6 changes: 2 additions & 4 deletions .github/workflows/clippy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ jobs:
run: cargo clippy -p test_arch_feature
- name: Clippy test_array
run: cargo clippy -p test_array
- name: Clippy test_async
run: cargo clippy -p test_async
- name: Clippy test_bcrypt
run: cargo clippy -p test_bcrypt
- name: Clippy test_calling_convention
Expand Down Expand Up @@ -173,10 +175,6 @@ jobs:
run: cargo clippy -p test_event
- name: Clippy test_extensions
run: cargo clippy -p test_extensions
- name: Clippy test_futures
run: cargo clippy -p test_futures
- name: Clippy test_futures_impl
run: cargo clippy -p test_futures_impl
- name: Clippy test_handles
run: cargo clippy -p test_handles
- name: Clippy test_helpers
Expand Down
10 changes: 4 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ jobs:
run: cargo test -p test_arch_feature --target ${{ matrix.target }} ${{ matrix.etc }}
- name: Test test_array
run: cargo test -p test_array --target ${{ matrix.target }} ${{ matrix.etc }}
- name: Test test_async
run: cargo test -p test_async --target ${{ matrix.target }} ${{ matrix.etc }}
- name: Test test_bcrypt
run: cargo test -p test_bcrypt --target ${{ matrix.target }} ${{ matrix.etc }}
- name: Test test_calling_convention
Expand Down Expand Up @@ -199,10 +201,6 @@ jobs:
run: cargo test -p test_event --target ${{ matrix.target }} ${{ matrix.etc }}
- name: Test test_extensions
run: cargo test -p test_extensions --target ${{ matrix.target }} ${{ matrix.etc }}
- name: Test test_futures
run: cargo test -p test_futures --target ${{ matrix.target }} ${{ matrix.etc }}
- name: Test test_futures_impl
run: cargo test -p test_futures_impl --target ${{ matrix.target }} ${{ matrix.etc }}
- name: Test test_handles
run: cargo test -p test_handles --target ${{ matrix.target }} ${{ matrix.etc }}
- name: Test test_helpers
Expand Down Expand Up @@ -255,10 +253,10 @@ jobs:
run: cargo test -p test_result --target ${{ matrix.target }} ${{ matrix.etc }}
- name: Test test_return_handle
run: cargo test -p test_return_handle --target ${{ matrix.target }} ${{ matrix.etc }}
- name: Clean
run: cargo clean
- name: Test test_return_struct
run: cargo test -p test_return_struct --target ${{ matrix.target }} ${{ matrix.etc }}
- name: Clean
run: cargo clean
- name: Test test_riddle
run: cargo test -p test_riddle --target ${{ matrix.target }} ${{ matrix.etc }}
- name: Test test_standalone
Expand Down
2 changes: 2 additions & 0 deletions crates/libs/windows/src/extensions/Foundation.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
pub mod Async;
#[cfg(feature = "implement")]
pub mod AsyncReady;
#[cfg(feature = "implement")]
pub mod AsyncSpawn;
#[cfg(feature = "Foundation_Collections")]
pub mod Collections;
#[cfg(feature = "Foundation_Numerics")]
Expand Down
13 changes: 8 additions & 5 deletions crates/libs/windows/src/extensions/Foundation/Async.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::core::{imp::Waiter, Interface, Result, RuntimeType};
use crate::Foundation::{AsyncActionCompletedHandler, AsyncActionWithProgressCompletedHandler, AsyncOperationCompletedHandler, AsyncOperationWithProgressCompletedHandler};
use crate::Foundation::{AsyncStatus, IAsyncAction, IAsyncActionWithProgress, IAsyncInfo, IAsyncOperation, IAsyncOperationWithProgress};
use crate::core::{imp::Waiter, *};
use crate::Foundation::*;
use std::future::{Future, IntoFuture};
use std::pin::Pin;
use std::sync::{Arc, Mutex};
Expand All @@ -17,10 +16,10 @@ use std::task::{Context, Poll, Waker};
// implementation below can be reused for all of them.
pub trait Async: Interface {
// The type of value produced on completion.
type Output;
type Output: Clone;

// The type of the delegate use for completion notification.
type CompletedHandler;
type CompletedHandler: Clone;

// Sets the handler or callback to invoke when execution completes. This handler can only be set once.
fn set_completed<F: Fn() + Send + 'static>(&self, handler: F) -> Result<()>;
Expand Down Expand Up @@ -237,6 +236,7 @@ impl<T: RuntimeType, P: RuntimeType> IntoFuture for IAsyncOperationWithProgress<
//

impl IAsyncAction {
/// Waits for the `IAsyncAction` to finish.
pub fn get(&self) -> Result<()> {
if self.Status()? == AsyncStatus::Started {
let (_waiter, signaler) = Waiter::new()?;
Expand All @@ -253,6 +253,7 @@ impl IAsyncAction {
}

impl<T: RuntimeType> IAsyncOperation<T> {
/// Waits for the `IAsyncOperation<T>` to finish.
pub fn get(&self) -> Result<T> {
if self.Status()? == AsyncStatus::Started {
let (_waiter, signaler) = Waiter::new()?;
Expand All @@ -269,6 +270,7 @@ impl<T: RuntimeType> IAsyncOperation<T> {
}

impl<P: RuntimeType> IAsyncActionWithProgress<P> {
/// Waits for the `IAsyncActionWithProgress<P>` to finish.
pub fn get(&self) -> Result<()> {
if self.Status()? == AsyncStatus::Started {
let (_waiter, signaler) = Waiter::new()?;
Expand All @@ -285,6 +287,7 @@ impl<P: RuntimeType> IAsyncActionWithProgress<P> {
}

impl<T: RuntimeType, P: RuntimeType> IAsyncOperationWithProgress<T, P> {
/// Waits for the `IAsyncOperationWithProgress<T, P>` to finish.
pub fn get(&self) -> Result<T> {
if self.Status()? == AsyncStatus::Started {
let (_waiter, signaler) = Waiter::new()?;
Expand Down
6 changes: 5 additions & 1 deletion crates/libs/windows/src/extensions/Foundation/AsyncReady.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ impl<T: Async> ReadyState<T> {
// 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: Option<&T::CompletedHandler>) -> Result<()> {
if self.set_completed.swap(true, Ordering::SeqCst) == false {
if !self.set_completed.swap(true, Ordering::SeqCst) {
if let Some(handler) = handler {
sender.invoke_completed(handler, self.status());
}
Expand Down Expand Up @@ -195,24 +195,28 @@ impl<T: RuntimeType, P: RuntimeType> IAsyncOperationWithProgress_Impl<T, P> for
}

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()
}
Expand Down
Loading

0 comments on commit ef06753

Please sign in to comment.