Snap for 10447354 from f993c7c745fcbf9b0069e62284e574f32d1c2965 to mainline-wifi-release

Change-Id: Icad813c9bbda665005eea3df9949bdff7eecc5e6
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 77486f4..915917d 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
 {
   "git": {
-    "sha1": "fc1e3250219170e31cddb8857a276cba7dd08d44"
+    "sha1": "5e3693a350f96244151081d2c030208cd15f9572"
   },
   "path_in_vcs": "futures-executor"
 }
\ No newline at end of file
diff --git a/Android.bp b/Android.bp
index ebd9f28..c11e245 100644
--- a/Android.bp
+++ b/Android.bp
@@ -39,12 +39,67 @@
     ],
 }
 
+rust_test {
+    name: "futures-executor_test_src_lib",
+    host_supported: true,
+    crate_name: "futures_executor",
+    cargo_env_compat: true,
+    cargo_pkg_version: "0.3.26",
+    srcs: ["src/lib.rs"],
+    test_suites: ["general-tests"],
+    auto_gen_config: true,
+    test_options: {
+        unit_test: true,
+    },
+    edition: "2018",
+    features: [
+        "num_cpus",
+        "std",
+        "thread-pool",
+    ],
+    rustlibs: [
+        "libfutures",
+        "libfutures_core",
+        "libfutures_task",
+        "libfutures_util",
+        "libnum_cpus",
+    ],
+}
+
+rust_test {
+    name: "futures-executor_test_tests_local_pool",
+    host_supported: true,
+    crate_name: "local_pool",
+    cargo_env_compat: true,
+    cargo_pkg_version: "0.3.26",
+    srcs: ["tests/local_pool.rs"],
+    test_suites: ["general-tests"],
+    auto_gen_config: true,
+    test_options: {
+        unit_test: true,
+    },
+    edition: "2018",
+    features: [
+        "num_cpus",
+        "std",
+        "thread-pool",
+    ],
+    rustlibs: [
+        "libfutures",
+        "libfutures_core",
+        "libfutures_executor",
+        "libfutures_task",
+        "libfutures_util",
+        "libnum_cpus",
+    ],
+}
+
 rust_library {
     name: "libfutures_executor",
     host_supported: true,
     crate_name: "futures_executor",
     cargo_env_compat: true,
-    cargo_pkg_version: "0.3.21",
+    cargo_pkg_version: "0.3.26",
     srcs: ["src/lib.rs"],
     edition: "2018",
     features: [
@@ -60,9 +115,11 @@
     ],
     apex_available: [
         "//apex_available:platform",
-        "com.android.bluetooth",
+        "com.android.btservices",
         "com.android.resolv",
         "com.android.virt",
     ],
+    product_available: true,
+    vendor_available: true,
     min_sdk_version: "29",
 }
diff --git a/Cargo.toml b/Cargo.toml
index 4b79bba..e2202e6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,11 +13,12 @@
 edition = "2018"
 rust-version = "1.45"
 name = "futures-executor"
-version = "0.3.21"
+version = "0.3.26"
 description = """
 Executors for asynchronous tasks based on the futures-rs library.
 """
 homepage = "https://rust-lang.github.io/futures-rs"
+readme = "README.md"
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/rust-lang/futures-rs"
 
@@ -29,15 +30,15 @@
 ]
 
 [dependencies.futures-core]
-version = "0.3.21"
+version = "0.3.26"
 default-features = false
 
 [dependencies.futures-task]
-version = "0.3.21"
+version = "0.3.26"
 default-features = false
 
 [dependencies.futures-util]
-version = "0.3.21"
+version = "0.3.26"
 default-features = false
 
 [dependencies.num_cpus]
@@ -45,6 +46,7 @@
 optional = true
 
 [dev-dependencies]
+futures = "0.3.21"
 
 [features]
 default = ["std"]
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index dae5f22..3ee3059 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
 [package]
 name = "futures-executor"
-version = "0.3.21"
+version = "0.3.26"
 edition = "2018"
 rust-version = "1.45"
 license = "MIT OR Apache-2.0"
@@ -16,13 +16,13 @@
 thread-pool = ["std", "num_cpus"]
 
 [dependencies]
-futures-core = { path = "../futures-core", version = "0.3.21", default-features = false }
-futures-task = { path = "../futures-task", version = "0.3.21", default-features = false }
-futures-util = { path = "../futures-util", version = "0.3.21", default-features = false }
+futures-core = { path = "../futures-core", version = "0.3.26", default-features = false }
+futures-task = { path = "../futures-task", version = "0.3.26", default-features = false }
+futures-util = { path = "../futures-util", version = "0.3.26", default-features = false }
 num_cpus = { version = "1.8.0", optional = true }
 
 [dev-dependencies]
-futures = { path = "../futures" }
+futures = { path = "../futures", features = ["thread-pool"] }
 
 [package.metadata.docs.rs]
 all-features = true
diff --git a/METADATA b/METADATA
index 26071bc..594dff2 100644
--- a/METADATA
+++ b/METADATA
@@ -1,3 +1,7 @@
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update rust/crates/futures-executor
+# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
+
 name: "futures-executor"
 description: "Executors for asynchronous tasks based on the futures-rs library."
 third_party {
@@ -7,13 +11,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/futures-executor/futures-executor-0.3.21.crate"
+    value: "https://static.crates.io/crates/futures-executor/futures-executor-0.3.26.crate"
   }
-  version: "0.3.21"
+  version: "0.3.26"
   license_type: NOTICE
   last_upgrade_date {
-    year: 2022
-    month: 3
-    day: 1
+    year: 2023
+    month: 2
+    day: 15
   }
 }
diff --git a/TEST_MAPPING b/TEST_MAPPING
index e2df61d..4dcae13 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -5,35 +5,47 @@
       "path": "external/rust/crates/anyhow"
     },
     {
+      "path": "external/rust/crates/futures-channel"
+    },
+    {
+      "path": "external/rust/crates/futures-test"
+    },
+    {
       "path": "external/rust/crates/tokio"
+    },
+    {
+      "path": "packages/modules/DnsResolver"
+    },
+    {
+      "path": "packages/modules/Virtualization/authfs"
+    },
+    {
+      "path": "packages/modules/Virtualization/virtualizationmanager"
+    },
+    {
+      "path": "packages/modules/Virtualization/zipfuse"
+    },
+    {
+      "path": "system/security/keystore2"
+    },
+    {
+      "path": "system/security/keystore2/legacykeystore"
     }
   ],
   "presubmit": [
     {
-      "name": "ZipFuseTest"
+      "name": "futures-executor_test_src_lib"
     },
     {
-      "name": "authfs_device_test_src_lib"
-    },
-    {
-      "name": "doh_unit_test"
-    },
-    {
-      "name": "virtualizationservice_device_test"
+      "name": "futures-executor_test_tests_local_pool"
     }
   ],
   "presubmit-rust": [
     {
-      "name": "ZipFuseTest"
+      "name": "futures-executor_test_src_lib"
     },
     {
-      "name": "authfs_device_test_src_lib"
-    },
-    {
-      "name": "doh_unit_test"
-    },
-    {
-      "name": "virtualizationservice_device_test"
+      "name": "futures-executor_test_tests_local_pool"
     }
   ]
 }
diff --git a/cargo2android.json b/cargo2android.json
index da40e17..dde71ca 100644
--- a/cargo2android.json
+++ b/cargo2android.json
@@ -1,7 +1,7 @@
 {
   "apex-available": [
     "//apex_available:platform",
-    "com.android.bluetooth",
+    "com.android.btservices",
     "com.android.resolv",
     "com.android.virt"
   ],
@@ -9,5 +9,6 @@
   "device": true,
   "features": "thread-pool",
   "min-sdk-version": "29",
-  "run": true
+  "run": true,
+  "tests": true
 }
diff --git a/patches/Cargo.toml.patch b/patches/Cargo.toml.patch
new file mode 100644
index 0000000..2dbe263
--- /dev/null
+++ b/patches/Cargo.toml.patch
@@ -0,0 +1,12 @@
+diff --git a/Cargo.toml b/Cargo.toml
+index 4b79bba..bf8fbf2 100644
+--- a/Cargo.toml
++++ b/Cargo.toml
+@@ -45,6 +45,7 @@ version = "1.8.0"
+ optional = true
+ 
+ [dev-dependencies]
++futures = "0.3.21"
+ 
+ [features]
+ default = ["std"]
diff --git a/src/enter.rs b/src/enter.rs
index 5895a9e..cb58c30 100644
--- a/src/enter.rs
+++ b/src/enter.rs
@@ -34,7 +34,7 @@
 /// executor.
 ///
 /// Executor implementations should call this function before beginning to
-/// execute a tasks, and drop the returned [`Enter`](Enter) value after
+/// execute a task, and drop the returned [`Enter`](Enter) value after
 /// completing task execution:
 ///
 /// ```
diff --git a/src/local_pool.rs b/src/local_pool.rs
index bee96d8..8a9bc2f 100644
--- a/src/local_pool.rs
+++ b/src/local_pool.rs
@@ -63,7 +63,7 @@
 impl ArcWake for ThreadNotify {
     fn wake_by_ref(arc_self: &Arc<Self>) {
         // Make sure the wakeup is remembered until the next `park()`.
-        let unparked = arc_self.unparked.swap(true, Ordering::Relaxed);
+        let unparked = arc_self.unparked.swap(true, Ordering::Release);
         if !unparked {
             // If the thread has not been unparked yet, it must be done
             // now. If it was actually parked, it will run again,
@@ -90,33 +90,21 @@
             if let Poll::Ready(t) = f(&mut cx) {
                 return t;
             }
-            // Consume the wakeup that occurred while executing `f`, if any.
-            let unparked = thread_notify.unparked.swap(false, Ordering::Acquire);
-            if !unparked {
+
+            // Wait for a wakeup.
+            while !thread_notify.unparked.swap(false, Ordering::Acquire) {
                 // No wakeup occurred. It may occur now, right before parking,
                 // but in that case the token made available by `unpark()`
                 // is guaranteed to still be available and `park()` is a no-op.
                 thread::park();
-                // When the thread is unparked, `unparked` will have been set
-                // and needs to be unset before the next call to `f` to avoid
-                // a redundant loop iteration.
-                thread_notify.unparked.store(false, Ordering::Release);
             }
         }
     })
 }
 
-fn poll_executor<T, F: FnMut(&mut Context<'_>) -> T>(mut f: F) -> T {
-    let _enter = enter().expect(
-        "cannot execute `LocalPool` executor from within \
-         another executor",
-    );
-
-    CURRENT_THREAD_NOTIFY.with(|thread_notify| {
-        let waker = waker_ref(thread_notify);
-        let mut cx = Context::from_waker(&waker);
-        f(&mut cx)
-    })
+/// Check for a wakeup, but don't consume it.
+fn woken() -> bool {
+    CURRENT_THREAD_NOTIFY.with(|thread_notify| thread_notify.unparked.load(Ordering::Acquire))
 }
 
 impl LocalPool {
@@ -212,20 +200,26 @@
     /// further use of one of the pool's run or poll methods.
     /// Though only one task will be completed, progress may be made on multiple tasks.
     pub fn try_run_one(&mut self) -> bool {
-        poll_executor(|ctx| {
+        run_executor(|cx| {
             loop {
-                let ret = self.poll_pool_once(ctx);
+                self.drain_incoming();
 
-                // return if we have executed a future
-                if let Poll::Ready(Some(_)) = ret {
-                    return true;
+                match self.pool.poll_next_unpin(cx) {
+                    // Success!
+                    Poll::Ready(Some(())) => return Poll::Ready(true),
+                    // The pool was empty.
+                    Poll::Ready(None) => return Poll::Ready(false),
+                    Poll::Pending => (),
                 }
 
-                // if there are no new incoming futures
-                // then there is no feature that can make progress
-                // and we can return without having completed a single future
-                if self.incoming.borrow().is_empty() {
-                    return false;
+                if !self.incoming.borrow().is_empty() {
+                    // New tasks were spawned; try again.
+                    continue;
+                } else if woken() {
+                    // The pool yielded to us, but there's more progress to be made.
+                    return Poll::Pending;
+                } else {
+                    return Poll::Ready(false);
                 }
             }
         })
@@ -257,44 +251,52 @@
     /// of the pool's run or poll methods. While the function is running, all tasks
     /// in the pool will try to make progress.
     pub fn run_until_stalled(&mut self) {
-        poll_executor(|ctx| {
-            let _ = self.poll_pool(ctx);
+        run_executor(|cx| match self.poll_pool(cx) {
+            // The pool is empty.
+            Poll::Ready(()) => Poll::Ready(()),
+            Poll::Pending => {
+                if woken() {
+                    Poll::Pending
+                } else {
+                    // We're stalled for now.
+                    Poll::Ready(())
+                }
+            }
         });
     }
 
-    // Make maximal progress on the entire pool of spawned task, returning `Ready`
-    // if the pool is empty and `Pending` if no further progress can be made.
+    /// Poll `self.pool`, re-filling it with any newly-spawned tasks.
+    /// Repeat until either the pool is empty, or it returns `Pending`.
+    ///
+    /// Returns `Ready` if the pool was empty, and `Pending` otherwise.
+    ///
+    /// NOTE: the pool may call `wake`, so `Pending` doesn't necessarily
+    /// mean that the pool can't make progress.
     fn poll_pool(&mut self, cx: &mut Context<'_>) -> Poll<()> {
-        // state for the FuturesUnordered, which will never be used
         loop {
-            let ret = self.poll_pool_once(cx);
+            self.drain_incoming();
 
-            // we queued up some new tasks; add them and poll again
+            let pool_ret = self.pool.poll_next_unpin(cx);
+
+            // We queued up some new tasks; add them and poll again.
             if !self.incoming.borrow().is_empty() {
                 continue;
             }
 
-            // no queued tasks; we may be done
-            match ret {
-                Poll::Pending => return Poll::Pending,
+            match pool_ret {
+                Poll::Ready(Some(())) => continue,
                 Poll::Ready(None) => return Poll::Ready(()),
-                _ => {}
+                Poll::Pending => return Poll::Pending,
             }
         }
     }
 
-    // Try make minimal progress on the pool of spawned tasks
-    fn poll_pool_once(&mut self, cx: &mut Context<'_>) -> Poll<Option<()>> {
-        // empty the incoming queue of newly-spawned tasks
-        {
-            let mut incoming = self.incoming.borrow_mut();
-            for task in incoming.drain(..) {
-                self.pool.push(task)
-            }
+    /// Empty the incoming queue of newly-spawned tasks.
+    fn drain_incoming(&mut self) {
+        let mut incoming = self.incoming.borrow_mut();
+        for task in incoming.drain(..) {
+            self.pool.push(task)
         }
-
-        // try to execute the next ready future
-        self.pool.poll_next_unpin(cx)
     }
 }
 
diff --git a/src/thread_pool.rs b/src/thread_pool.rs
index 5e1f586..5371008 100644
--- a/src/thread_pool.rs
+++ b/src/thread_pool.rs
@@ -108,12 +108,15 @@
     /// completion.
     ///
     /// ```
+    /// # {
     /// use futures::executor::ThreadPool;
     ///
     /// let pool = ThreadPool::new().unwrap();
     ///
     /// let future = async { /* ... */ };
     /// pool.spawn_ok(future);
+    /// # }
+    /// # std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371
     /// ```
     ///
     /// > **Note**: This method is similar to `SpawnExt::spawn`, except that
@@ -346,9 +349,8 @@
 
 impl ArcWake for WakeHandle {
     fn wake_by_ref(arc_self: &Arc<Self>) {
-        match arc_self.mutex.notify() {
-            Ok(task) => arc_self.exec.state.send(Message::Run(task)),
-            Err(()) => {}
+        if let Ok(task) = arc_self.mutex.notify() {
+            arc_self.exec.state.send(Message::Run(task))
         }
     }
 }
@@ -360,16 +362,19 @@
 
     #[test]
     fn test_drop_after_start() {
-        let (tx, rx) = mpsc::sync_channel(2);
-        let _cpu_pool = ThreadPoolBuilder::new()
-            .pool_size(2)
-            .after_start(move |_| tx.send(1).unwrap())
-            .create()
-            .unwrap();
+        {
+            let (tx, rx) = mpsc::sync_channel(2);
+            let _cpu_pool = ThreadPoolBuilder::new()
+                .pool_size(2)
+                .after_start(move |_| tx.send(1).unwrap())
+                .create()
+                .unwrap();
 
-        // After ThreadPoolBuilder is deconstructed, the tx should be dropped
-        // so that we can use rx as an iterator.
-        let count = rx.into_iter().count();
-        assert_eq!(count, 2);
+            // After ThreadPoolBuilder is deconstructed, the tx should be dropped
+            // so that we can use rx as an iterator.
+            let count = rx.into_iter().count();
+            assert_eq!(count, 2);
+        }
+        std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371
     }
 }
diff --git a/tests/local_pool.rs b/tests/local_pool.rs
index 9b1316b..72ce74b 100644
--- a/tests/local_pool.rs
+++ b/tests/local_pool.rs
@@ -1,7 +1,7 @@
 use futures::channel::oneshot;
 use futures::executor::LocalPool;
 use futures::future::{self, lazy, poll_fn, Future};
-use futures::task::{Context, LocalSpawn, Poll, Spawn, Waker};
+use futures::task::{Context, LocalSpawn, LocalSpawnExt, Poll, Spawn, SpawnExt, Waker};
 use std::cell::{Cell, RefCell};
 use std::pin::Pin;
 use std::rc::Rc;
@@ -288,7 +288,7 @@
 
 #[test]
 fn run_until_stalled_executes_all_ready() {
-    const ITER: usize = 200;
+    const ITER: usize = if cfg!(miri) { 50 } else { 200 };
     const PER_ITER: usize = 3;
 
     let cnt = Rc::new(Cell::new(0));
@@ -432,3 +432,65 @@
 
     futures::executor::block_on(future)
 }
+
+struct SelfWaking {
+    wakeups_remaining: Rc<RefCell<usize>>,
+}
+
+impl Future for SelfWaking {
+    type Output = ();
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        if *self.wakeups_remaining.borrow() != 0 {
+            *self.wakeups_remaining.borrow_mut() -= 1;
+            cx.waker().wake_by_ref();
+        }
+
+        Poll::Pending
+    }
+}
+
+/// Regression test for https://github.com/rust-lang/futures-rs/pull/2593
+///
+/// The issue was that self-waking futures could cause `run_until_stalled`
+/// to exit early, even when progress could still be made.
+#[test]
+fn self_waking_run_until_stalled() {
+    let wakeups_remaining = Rc::new(RefCell::new(10));
+
+    let mut pool = LocalPool::new();
+    let spawner = pool.spawner();
+    for _ in 0..3 {
+        let wakeups_remaining = Rc::clone(&wakeups_remaining);
+        spawner.spawn_local(SelfWaking { wakeups_remaining }).unwrap();
+    }
+
+    // This should keep polling until there are no more wakeups.
+    pool.run_until_stalled();
+
+    assert_eq!(*wakeups_remaining.borrow(), 0);
+}
+
+/// Regression test for https://github.com/rust-lang/futures-rs/pull/2593
+///
+/// The issue was that self-waking futures could cause `try_run_one`
+/// to exit early, even when progress could still be made.
+#[test]
+fn self_waking_try_run_one() {
+    let wakeups_remaining = Rc::new(RefCell::new(10));
+
+    let mut pool = LocalPool::new();
+    let spawner = pool.spawner();
+    for _ in 0..3 {
+        let wakeups_remaining = Rc::clone(&wakeups_remaining);
+        spawner.spawn_local(SelfWaking { wakeups_remaining }).unwrap();
+    }
+
+    spawner.spawn(future::ready(())).unwrap();
+
+    // The `ready` future should complete.
+    assert!(pool.try_run_one());
+
+    // The self-waking futures are each polled once.
+    assert_eq!(*wakeups_remaining.borrow(), 7);
+}