Snap for 11400057 from a79678d1fbf992c8dc5c28379a5faa10ea9fab4c to simpleperf-release

Change-Id: Ib0253bebb855ba2b08a9a0726ef678b05d3fb551
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 3fade60..635c197 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
 {
   "git": {
-    "sha1": "5e3693a350f96244151081d2c030208cd15f9572"
+    "sha1": "de1a0fd64a1bcae9a1534ed4da1699632993cc26"
   },
   "path_in_vcs": "futures-channel"
 }
\ No newline at end of file
diff --git a/Android.bp b/Android.bp
index c1c089d..7fd20e8 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,4 +1,4 @@
-// This file is generated by cargo2android.py --config cargo2android.json.
+// This file is generated by cargo_embargo.
 // Do not modify this file as changes will be overridden on upgrade.
 
 package {
@@ -46,7 +46,7 @@
     host_supported: true,
     crate_name: "futures_channel",
     cargo_env_compat: true,
-    cargo_pkg_version: "0.3.26",
+    cargo_pkg_version: "0.3.30",
     srcs: ["src/lib.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -69,13 +69,18 @@
     ],
 }
 
-rust_defaults {
-    name: "futures-channel_test_defaults",
-    crate_name: "futures_channel",
+rust_test {
+    name: "futures-channel_test_tests_channel",
+    host_supported: true,
+    crate_name: "channel",
     cargo_env_compat: true,
-    cargo_pkg_version: "0.3.26",
+    cargo_pkg_version: "0.3.30",
+    srcs: ["tests/channel.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
+    test_options: {
+        unit_test: true,
+    },
     edition: "2018",
     features: [
         "alloc",
@@ -94,53 +99,119 @@
 }
 
 rust_test {
-    name: "futures-channel_test_tests_channel",
-    defaults: ["futures-channel_test_defaults"],
+    name: "futures-channel_test_tests_mpsc",
     host_supported: true,
-    srcs: ["tests/channel.rs"],
+    crate_name: "mpsc",
+    cargo_env_compat: true,
+    cargo_pkg_version: "0.3.30",
+    srcs: ["tests/mpsc.rs"],
+    test_suites: ["general-tests"],
+    auto_gen_config: true,
     test_options: {
         unit_test: true,
     },
+    edition: "2018",
+    features: [
+        "alloc",
+        "default",
+        "futures-sink",
+        "sink",
+        "std",
+    ],
+    rustlibs: [
+        "libfutures",
+        "libfutures_channel",
+        "libfutures_core",
+        "libfutures_sink",
+        "libfutures_test",
+    ],
 }
 
 rust_test {
     name: "futures-channel_test_tests_mpsc-close",
-    defaults: ["futures-channel_test_defaults"],
     host_supported: true,
+    crate_name: "mpsc_close",
+    cargo_env_compat: true,
+    cargo_pkg_version: "0.3.30",
     srcs: ["tests/mpsc-close.rs"],
+    test_suites: ["general-tests"],
+    auto_gen_config: true,
     test_options: {
         unit_test: true,
     },
+    edition: "2018",
+    features: [
+        "alloc",
+        "default",
+        "futures-sink",
+        "sink",
+        "std",
+    ],
+    rustlibs: [
+        "libfutures",
+        "libfutures_channel",
+        "libfutures_core",
+        "libfutures_sink",
+        "libfutures_test",
+    ],
 }
 
 rust_test {
     name: "futures-channel_test_tests_mpsc-size_hint",
-    defaults: ["futures-channel_test_defaults"],
     host_supported: true,
+    crate_name: "mpsc_size_hint",
+    cargo_env_compat: true,
+    cargo_pkg_version: "0.3.30",
     srcs: ["tests/mpsc-size_hint.rs"],
+    test_suites: ["general-tests"],
+    auto_gen_config: true,
     test_options: {
         unit_test: true,
     },
-}
-
-rust_test {
-    name: "futures-channel_test_tests_mpsc",
-    defaults: ["futures-channel_test_defaults"],
-    host_supported: true,
-    srcs: ["tests/mpsc.rs"],
-    test_options: {
-        unit_test: true,
-    },
+    edition: "2018",
+    features: [
+        "alloc",
+        "default",
+        "futures-sink",
+        "sink",
+        "std",
+    ],
+    rustlibs: [
+        "libfutures",
+        "libfutures_channel",
+        "libfutures_core",
+        "libfutures_sink",
+        "libfutures_test",
+    ],
 }
 
 rust_test {
     name: "futures-channel_test_tests_oneshot",
-    defaults: ["futures-channel_test_defaults"],
     host_supported: true,
+    crate_name: "oneshot",
+    cargo_env_compat: true,
+    cargo_pkg_version: "0.3.30",
     srcs: ["tests/oneshot.rs"],
+    test_suites: ["general-tests"],
+    auto_gen_config: true,
     test_options: {
         unit_test: true,
     },
+    edition: "2018",
+    features: [
+        "alloc",
+        "default",
+        "futures-sink",
+        "sink",
+        "std",
+    ],
+    rustlibs: [
+        "libfutures",
+        "libfutures_channel",
+        "libfutures_core",
+        "libfutures_sink",
+        "libfutures_test",
+    ],
 }
 
 rust_library {
@@ -148,7 +219,7 @@
     host_supported: true,
     crate_name: "futures_channel",
     cargo_env_compat: true,
-    cargo_pkg_version: "0.3.26",
+    cargo_pkg_version: "0.3.30",
     srcs: ["src/lib.rs"],
     edition: "2018",
     features: [
diff --git a/Cargo.toml b/Cargo.toml
index 869d735..2cec534 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,9 +11,9 @@
 
 [package]
 edition = "2018"
-rust-version = "1.45"
+rust-version = "1.56"
 name = "futures-channel"
-version = "0.3.26"
+version = "0.3.30"
 description = """
 Channels for asynchronous communication using futures-rs.
 """
@@ -30,11 +30,11 @@
 ]
 
 [dependencies.futures-core]
-version = "0.3.26"
+version = "0.3.30"
 default-features = false
 
 [dependencies.futures-sink]
-version = "0.3.26"
+version = "0.3.30"
 optional = true
 default-features = false
 
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 753fd46..7e0e9dd 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,8 +1,8 @@
 [package]
 name = "futures-channel"
-version = "0.3.26"
+version = "0.3.30"
 edition = "2018"
-rust-version = "1.45"
+rust-version = "1.56"
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/rust-lang/futures-rs"
 homepage = "https://rust-lang.github.io/futures-rs"
@@ -22,8 +22,8 @@
 cfg-target-has-atomic = []
 
 [dependencies]
-futures-core = { path = "../futures-core", version = "0.3.26", default-features = false }
-futures-sink = { path = "../futures-sink", version = "0.3.26", default-features = false, optional = true }
+futures-core = { path = "../futures-core", version = "0.3.30", default-features = false }
+futures-sink = { path = "../futures-sink", version = "0.3.30", default-features = false, optional = true }
 
 [dev-dependencies]
 futures = { path = "../futures", default-features = true }
diff --git a/METADATA b/METADATA
index 66ed9e7..48b4b03 100644
--- a/METADATA
+++ b/METADATA
@@ -1,23 +1,20 @@
 # This project was upgraded with external_updater.
-# Usage: tools/external_updater/updater.sh update rust/crates/futures-channel
-# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
+# Usage: tools/external_updater/updater.sh update external/rust/crates/futures-channel
+# For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md
 
 name: "futures-channel"
 description: "Channels for asynchronous communication using futures-rs."
 third_party {
-  url {
-    type: HOMEPAGE
-    value: "https://crates.io/crates/futures-channel"
-  }
-  url {
-    type: ARCHIVE
-    value: "https://static.crates.io/crates/futures-channel/futures-channel-0.3.26.crate"
-  }
-  version: "0.3.26"
   license_type: NOTICE
   last_upgrade_date {
-    year: 2023
+    year: 2024
     month: 2
-    day: 15
+    day: 1
+  }
+  homepage: "https://crates.io/crates/futures-channel"
+  identifier {
+    type: "Archive"
+    value: "https://static.crates.io/crates/futures-channel/futures-channel-0.3.30.crate"
+    version: "0.3.30"
   }
 }
diff --git a/README.md b/README.md
index 3287be9..e886bd1 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@
 futures-channel = "0.3"
 ```
 
-The current `futures-channel` requires Rust 1.45 or later.
+The current `futures-channel` requires Rust 1.56 or later.
 
 ## License
 
diff --git a/build.rs b/build.rs
deleted file mode 100644
index 05e0496..0000000
--- a/build.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-// The rustc-cfg listed below are considered public API, but it is *unstable*
-// and outside of the normal semver guarantees:
-//
-// - `futures_no_atomic_cas`
-//      Assume the target does *not* support atomic CAS operations.
-//      This is usually detected automatically by the build script, but you may
-//      need to enable it manually when building for custom targets or using
-//      non-cargo build systems that don't run the build script.
-//
-// With the exceptions mentioned above, the rustc-cfg emitted by the build
-// script are *not* public API.
-
-#![warn(rust_2018_idioms, single_use_lifetimes)]
-
-use std::env;
-
-include!("no_atomic_cas.rs");
-
-fn main() {
-    let target = match env::var("TARGET") {
-        Ok(target) => target,
-        Err(e) => {
-            println!(
-                "cargo:warning={}: unable to get TARGET environment variable: {}",
-                env!("CARGO_PKG_NAME"),
-                e
-            );
-            return;
-        }
-    };
-
-    // Note that this is `no_*`, not `has_*`. This allows treating
-    // `cfg(target_has_atomic = "ptr")` as true when the build script doesn't
-    // run. This is needed for compatibility with non-cargo build systems that
-    // don't run the build script.
-    if NO_ATOMIC_CAS.contains(&&*target) {
-        println!("cargo:rustc-cfg=futures_no_atomic_cas");
-    }
-
-    println!("cargo:rerun-if-changed=no_atomic_cas.rs");
-}
diff --git a/cargo2android.json b/cargo2android.json
deleted file mode 100644
index 4458799..0000000
--- a/cargo2android.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "apex-available": [
-    "//apex_available:platform",
-    "com.android.btservices",
-    "com.android.resolv",
-    "com.android.virt"
-  ],
-  "dependencies": true,
-  "device": true,
-  "features": "alloc,default,std,sink",
-  "min-sdk-version": "29",
-  "run": true,
-  "tests": true
-}
diff --git a/cargo_embargo.json b/cargo_embargo.json
new file mode 100644
index 0000000..8d7705e
--- /dev/null
+++ b/cargo_embargo.json
@@ -0,0 +1,17 @@
+{
+  "apex_available": [
+    "//apex_available:platform",
+    "com.android.btservices",
+    "com.android.resolv",
+    "com.android.virt"
+  ],
+  "features": [
+    "alloc",
+    "default",
+    "std",
+    "sink"
+  ],
+  "min_sdk_version": "29",
+  "run_cargo": false,
+  "tests": true
+}
diff --git a/no_atomic_cas.rs b/no_atomic_cas.rs
deleted file mode 100644
index 16ec628..0000000
--- a/no_atomic_cas.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-// This file is @generated by no_atomic_cas.sh.
-// It is not intended for manual editing.
-
-const NO_ATOMIC_CAS: &[&str] = &[
-    "armv4t-none-eabi",
-    "armv5te-none-eabi",
-    "avr-unknown-gnu-atmega328",
-    "bpfeb-unknown-none",
-    "bpfel-unknown-none",
-    "msp430-none-elf",
-    "riscv32i-unknown-none-elf",
-    "riscv32im-unknown-none-elf",
-    "riscv32imc-unknown-none-elf",
-    "thumbv4t-none-eabi",
-    "thumbv5te-none-eabi",
-    "thumbv6m-none-eabi",
-];
diff --git a/src/lib.rs b/src/lib.rs
index 4cd936d..f611e6b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -27,16 +27,16 @@
     )
 ))]
 
-#[cfg(not(futures_no_atomic_cas))]
+#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
 #[cfg(feature = "alloc")]
 extern crate alloc;
 
-#[cfg(not(futures_no_atomic_cas))]
+#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
 #[cfg(feature = "alloc")]
 mod lock;
-#[cfg(not(futures_no_atomic_cas))]
+#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
 #[cfg(feature = "std")]
 pub mod mpsc;
-#[cfg(not(futures_no_atomic_cas))]
+#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
 #[cfg(feature = "alloc")]
 pub mod oneshot;
diff --git a/src/mpsc/mod.rs b/src/mpsc/mod.rs
index cf45fe7..64f7526 100644
--- a/src/mpsc/mod.rs
+++ b/src/mpsc/mod.rs
@@ -119,12 +119,12 @@
 
 /// The transmission end of a bounded mpsc channel.
 ///
-/// This value is created by the [`channel`](channel) function.
+/// This value is created by the [`channel`] function.
 pub struct Sender<T>(Option<BoundedSenderInner<T>>);
 
 /// The transmission end of an unbounded mpsc channel.
 ///
-/// This value is created by the [`unbounded`](unbounded) function.
+/// This value is created by the [`unbounded`] function.
 pub struct UnboundedSender<T>(Option<UnboundedSenderInner<T>>);
 
 trait AssertKinds: Send + Sync + Clone {}
@@ -132,14 +132,14 @@
 
 /// The receiving end of a bounded mpsc channel.
 ///
-/// This value is created by the [`channel`](channel) function.
+/// This value is created by the [`channel`] function.
 pub struct Receiver<T> {
     inner: Option<Arc<BoundedInner<T>>>,
 }
 
 /// The receiving end of an unbounded mpsc channel.
 ///
-/// This value is created by the [`unbounded`](unbounded) function.
+/// This value is created by the [`unbounded`] function.
 pub struct UnboundedReceiver<T> {
     inner: Option<Arc<UnboundedInner<T>>>,
 }
@@ -343,9 +343,8 @@
 /// guaranteed slot in the channel capacity, and on top of that there are
 /// `buffer` "first come, first serve" slots available to all senders.
 ///
-/// The [`Receiver`](Receiver) returned implements the
-/// [`Stream`](futures_core::stream::Stream) trait, while [`Sender`](Sender) implements
-/// `Sink`.
+/// The [`Receiver`] returned implements the [`Stream`] trait, while [`Sender`]
+/// implements `Sink`.
 pub fn channel<T>(buffer: usize) -> (Sender<T>, Receiver<T>) {
     // Check that the requested buffer size does not exceed the maximum buffer
     // size permitted by the system.
@@ -842,6 +841,20 @@
         let ptr = self.0.as_ref().map(|inner| inner.ptr());
         ptr.hash(hasher);
     }
+
+    /// Return the number of messages in the queue or 0 if channel is disconnected.
+    pub fn len(&self) -> usize {
+        if let Some(sender) = &self.0 {
+            decode_state(sender.inner.state.load(SeqCst)).num_messages
+        } else {
+            0
+        }
+    }
+
+    /// Return false is channel has no queued messages, true otherwise.
+    pub fn is_empty(&self) -> bool {
+        self.len() == 0
+    }
 }
 
 impl<T> Clone for Sender<T> {
diff --git a/src/oneshot.rs b/src/oneshot.rs
index 70449f4..fe5b115 100644
--- a/src/oneshot.rs
+++ b/src/oneshot.rs
@@ -14,7 +14,7 @@
 
 /// A future for a value that will be provided by another asynchronous task.
 ///
-/// This is created by the [`channel`](channel) function.
+/// This is created by the [`channel`] function.
 #[must_use = "futures do nothing unless you `.await` or poll them"]
 pub struct Receiver<T> {
     inner: Arc<Inner<T>>,
@@ -22,7 +22,7 @@
 
 /// A means of transmitting a single value to another task.
 ///
-/// This is created by the [`channel`](channel) function.
+/// This is created by the [`channel`] function.
 pub struct Sender<T> {
     inner: Arc<Inner<T>>,
 }
@@ -332,8 +332,8 @@
     /// Completes this oneshot with a successful result.
     ///
     /// This function will consume `self` and indicate to the other end, the
-    /// [`Receiver`](Receiver), that the value provided is the result of the
-    /// computation this represents.
+    /// [`Receiver`], that the value provided is the result of the computation
+    /// this represents.
     ///
     /// If the value is successfully enqueued for the remote end to receive,
     /// then `Ok(())` is returned. If the receiving end was dropped before
@@ -343,7 +343,7 @@
     }
 
     /// Polls this `Sender` half to detect whether its associated
-    /// [`Receiver`](Receiver) has been dropped.
+    /// [`Receiver`] has been dropped.
     ///
     /// # Return values
     ///
@@ -359,10 +359,10 @@
     }
 
     /// Creates a future that resolves when this `Sender`'s corresponding
-    /// [`Receiver`](Receiver) half has hung up.
+    /// [`Receiver`] half has hung up.
     ///
     /// This is a utility wrapping [`poll_canceled`](Sender::poll_canceled)
-    /// to expose a [`Future`](core::future::Future).
+    /// to expose a [`Future`].
     pub fn cancellation(&mut self) -> Cancellation<'_, T> {
         Cancellation { inner: self }
     }
@@ -413,8 +413,8 @@
     }
 }
 
-/// Error returned from a [`Receiver`](Receiver) when the corresponding
-/// [`Sender`](Sender) is dropped.
+/// Error returned from a [`Receiver`] when the corresponding [`Sender`] is
+/// dropped.
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
 pub struct Canceled;
 
diff --git a/tests/mpsc.rs b/tests/mpsc.rs
index 444c8e1..f5d7198 100644
--- a/tests/mpsc.rs
+++ b/tests/mpsc.rs
@@ -632,3 +632,26 @@
     let item = block_on(rx.next()).unwrap();
     assert_eq!(item, 2);
 }
+
+/// Test that empty channel has zero length and that non-empty channel has length equal to number
+/// of enqueued items
+#[test]
+fn unbounded_len() {
+    let (tx, mut rx) = mpsc::unbounded();
+    assert_eq!(tx.len(), 0);
+    assert!(tx.is_empty());
+    tx.unbounded_send(1).unwrap();
+    assert_eq!(tx.len(), 1);
+    assert!(!tx.is_empty());
+    tx.unbounded_send(2).unwrap();
+    assert_eq!(tx.len(), 2);
+    assert!(!tx.is_empty());
+    let item = block_on(rx.next()).unwrap();
+    assert_eq!(item, 1);
+    assert_eq!(tx.len(), 1);
+    assert!(!tx.is_empty());
+    let item = block_on(rx.next()).unwrap();
+    assert_eq!(item, 2);
+    assert_eq!(tx.len(), 0);
+    assert!(tx.is_empty());
+}