diff options
Diffstat (limited to '')
-rw-r--r-- | xpcom/rust/gtest/moz_task/test.rs | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/xpcom/rust/gtest/moz_task/test.rs b/xpcom/rust/gtest/moz_task/test.rs new file mode 100644 index 0000000000..fa4c0af852 --- /dev/null +++ b/xpcom/rust/gtest/moz_task/test.rs @@ -0,0 +1,78 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use moz_task; +use std::{ + future::Future, + pin::Pin, + task::{Context, Poll, Waker}, +}; + +/// Demo `Future` to demonstrate executing futures to completion via `nsIEventTarget`. +struct MyFuture { + poll_count: u32, + waker: Option<Waker>, + expect_main_thread: bool, +} + +impl MyFuture { + fn new(expect_main_thread: bool) -> Self { + Self { + poll_count: 0, + waker: None, + expect_main_thread, + } + } +} + +impl Future for MyFuture { + type Output = u32; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<u32> { + assert_eq!(moz_task::is_main_thread(), self.expect_main_thread); + + self.poll_count += 1; + + if let Some(waker) = &mut self.waker { + if !waker.will_wake(cx.waker()) { + *waker = cx.waker().clone(); + } + } else { + let waker = cx.waker().clone(); + self.waker = Some(waker); + } + + println!("Poll count = {}", self.poll_count); + if self.poll_count > 5 { + Poll::Ready(self.poll_count) + } else { + // Just notify the task that we need to re-polled. + if let Some(waker) = &self.waker { + waker.wake_by_ref(); + } + Poll::Pending + } + } +} + +#[no_mangle] +pub extern "C" fn Rust_Future(it_worked: *mut bool) { + let future = async move { + assert_eq!(MyFuture::new(true).await, 6); + assert_eq!( + moz_task::spawn_local("Rust_Future inner spawn_local", MyFuture::new(true)).await, + 6 + ); + assert_eq!( + moz_task::spawn("Rust_Future inner spawn", MyFuture::new(false)).await, + 6 + ); + unsafe { + *it_worked = true; + } + }; + unsafe { + moz_task::gtest_only::spin_event_loop_until("Rust_Future", future).unwrap(); + }; +} |