Upgrade crossbeam-channel to 0.5.11

This project was upgraded with external_updater.
Usage: tools/external_updater/updater.sh update external/rust/crates/crossbeam-channel
For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md

Test: TreeHugger
Change-Id: I1e45a2ff060bfe8d1d9863a27176c7a872c6a38c
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 548f675..3e11e4a 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
 {
   "git": {
-    "sha1": "721382b00b5dadd81954ed66764d547e2f1bb7a3"
+    "sha1": "9c3182abebb36bdc9446d75d4644190fef70fa01"
   },
   "path_in_vcs": "crossbeam-channel"
 }
\ No newline at end of file
diff --git a/Android.bp b/Android.bp
index 1848370..8f6f5a4 100644
--- a/Android.bp
+++ b/Android.bp
@@ -47,18 +47,14 @@
     host_supported: true,
     crate_name: "crossbeam_channel",
     cargo_env_compat: true,
-    cargo_pkg_version: "0.5.7",
+    cargo_pkg_version: "0.5.11",
     srcs: ["src/lib.rs"],
-    edition: "2018",
+    edition: "2021",
     features: [
-        "crossbeam-utils",
         "default",
         "std",
     ],
-    rustlibs: [
-        "libcfg_if",
-        "libcrossbeam_utils",
-    ],
+    rustlibs: ["libcrossbeam_utils"],
     apex_available: [
         "//apex_available:platform",
         "//apex_available:anyapex",
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3277f15..2f172fb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,17 +1,42 @@
+# Version 0.5.11
+
+- Remove dependency on `cfg-if`. (#1072)
+
+# Version 0.5.10
+
+- Relax the minimum supported Rust version to 1.60. (#1056)
+- Optimize `Drop` implementation of bounded channel. (#1057)
+
+# Version 0.5.9
+
+- Bump the minimum supported Rust version to 1.61. (#1037)
+
+# Version 0.5.8
+
+- Fix race condition in unbounded channel. (#972)
+
 # Version 0.5.7
 
+**Note:** This release has been yanked due to bug fixed in 0.5.8.
+
 - Improve handling of very large timeout. (#953)
 
 # Version 0.5.6
 
+**Note:** This release has been yanked due to bug fixed in 0.5.8.
+
 - Bump the minimum supported Rust version to 1.38. (#877)
 
 # Version 0.5.5
 
+**Note:** This release has been yanked due to bug fixed in 0.5.8.
+
 - Replace Spinlock with Mutex. (#835)
 
 # Version 0.5.4
 
+**Note:** This release has been yanked due to bug fixed in 0.5.8.
+
 - Workaround a bug in upstream related to TLS access on AArch64 Linux. (#802)
 
 # Version 0.5.3
@@ -28,6 +53,8 @@
 
 # Version 0.5.1
 
+**Note:** This release has been yanked due to bug fixed in 0.5.8.
+
 - Fix memory leak in unbounded channel. (#669)
 
 # Version 0.5.0
diff --git a/Cargo.lock b/Cargo.lock
index e4b10f4..051ab47 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -10,9 +10,8 @@
 
 [[package]]
 name = "crossbeam-channel"
-version = "0.5.7"
+version = "0.5.11"
 dependencies = [
- "cfg-if",
  "crossbeam-utils",
  "num_cpus",
  "rand",
@@ -21,18 +20,18 @@
 
 [[package]]
 name = "crossbeam-utils"
-version = "0.8.15"
+version = "0.8.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b"
+checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c"
 dependencies = [
  "cfg-if",
 ]
 
 [[package]]
 name = "getrandom"
-version = "0.2.8"
+version = "0.2.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
+checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
 dependencies = [
  "cfg-if",
  "libc",
@@ -41,24 +40,21 @@
 
 [[package]]
 name = "hermit-abi"
-version = "0.2.6"
+version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
-dependencies = [
- "libc",
-]
+checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
 
 [[package]]
 name = "libc"
-version = "0.2.139"
+version = "0.2.152"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
+checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7"
 
 [[package]]
 name = "num_cpus"
-version = "1.15.0"
+version = "1.16.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
+checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
 dependencies = [
  "hermit-abi",
  "libc",
@@ -102,9 +98,9 @@
 
 [[package]]
 name = "signal-hook"
-version = "0.3.15"
+version = "0.3.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9"
+checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
 dependencies = [
  "libc",
  "signal-hook-registry",
diff --git a/Cargo.toml b/Cargo.toml
index b0e95c3..8b64867 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,10 +10,10 @@
 # See Cargo.toml.orig for the original contents.
 
 [package]
-edition = "2018"
-rust-version = "1.38"
+edition = "2021"
+rust-version = "1.60"
 name = "crossbeam-channel"
-version = "0.5.7"
+version = "0.5.11"
 description = "Multi-producer multi-consumer channels for message passing"
 homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-channel"
 readme = "README.md"
@@ -32,12 +32,8 @@
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/crossbeam-rs/crossbeam"
 
-[dependencies.cfg-if]
-version = "1"
-
 [dependencies.crossbeam-utils]
-version = "0.8"
-optional = true
+version = "0.8.18"
 default-features = false
 
 [dev-dependencies.num_cpus]
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 25c3678..5a39c18 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -4,9 +4,9 @@
 # - Update CHANGELOG.md
 # - Update README.md
 # - Create "crossbeam-channel-X.Y.Z" git tag
-version = "0.5.7"
-edition = "2018"
-rust-version = "1.38"
+version = "0.5.11"
+edition = "2021"
+rust-version = "1.60"
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/crossbeam-rs/crossbeam"
 homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-channel"
@@ -24,13 +24,7 @@
 std = ["crossbeam-utils/std"]
 
 [dependencies]
-cfg-if = "1"
-
-[dependencies.crossbeam-utils]
-version = "0.8"
-path = "../crossbeam-utils"
-default-features = false
-optional = true
+crossbeam-utils = { version = "0.8.18", path = "../crossbeam-utils", default-features = false }
 
 [dev-dependencies]
 num_cpus = "1.13.0"
diff --git a/METADATA b/METADATA
index d824734..a372576 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/crossbeam-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/crossbeam-channel
+# For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md
 
 name: "crossbeam-channel"
 description: "Multi-producer multi-consumer channels for message passing"
 third_party {
-  url {
-    type: HOMEPAGE
-    value: "https://crates.io/crates/crossbeam-channel"
-  }
-  url {
-    type: ARCHIVE
-    value: "https://static.crates.io/crates/crossbeam-channel/crossbeam-channel-0.5.7.crate"
-  }
-  version: "0.5.7"
   license_type: NOTICE
   last_upgrade_date {
-    year: 2023
-    month: 3
-    day: 6
+    year: 2024
+    month: 2
+    day: 1
+  }
+  homepage: "https://crates.io/crates/crossbeam-channel"
+  identifier {
+    type: "Archive"
+    value: "https://static.crates.io/crates/crossbeam-channel/crossbeam-channel-0.5.11.crate"
+    version: "0.5.11"
   }
 }
diff --git a/README.md b/README.md
index 4c42d86..a8a1a78 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@
 https://crates.io/crates/crossbeam-channel)
 [![Documentation](https://docs.rs/crossbeam-channel/badge.svg)](
 https://docs.rs/crossbeam-channel)
-[![Rust 1.38+](https://img.shields.io/badge/rust-1.38+-lightgray.svg)](
+[![Rust 1.60+](https://img.shields.io/badge/rust-1.60+-lightgray.svg)](
 https://www.rust-lang.org)
 [![chat](https://img.shields.io/discord/569610676205781012.svg?logo=discord)](https://discord.com/invite/JXYwgWZ)
 
@@ -48,7 +48,7 @@
 
 Crossbeam Channel supports stable Rust releases going back at least six months,
 and every time the minimum supported Rust version is increased, a new minor
-version is released. Currently, the minimum supported Rust version is 1.38.
+version is released. Currently, the minimum supported Rust version is 1.60.
 
 ## License
 
diff --git a/src/flavors/array.rs b/src/flavors/array.rs
index 63b82eb..ccc47b5 100644
--- a/src/flavors/array.rs
+++ b/src/flavors/array.rs
@@ -9,7 +9,7 @@
 //!   - <https://docs.google.com/document/d/1yIAYmbvL3JxOKOjuCyon7JhW4cSv1wy5hC0ApeGMV9s/pub>
 
 use std::cell::UnsafeCell;
-use std::mem::MaybeUninit;
+use std::mem::{self, MaybeUninit};
 use std::ptr;
 use std::sync::atomic::{self, AtomicUsize, Ordering};
 use std::time::Instant;
@@ -520,37 +520,38 @@
 
 impl<T> Drop for Channel<T> {
     fn drop(&mut self) {
-        // Get the index of the head.
-        let head = *self.head.get_mut();
-        let tail = *self.tail.get_mut();
+        if mem::needs_drop::<T>() {
+            // Get the index of the head.
+            let head = *self.head.get_mut();
+            let tail = *self.tail.get_mut();
 
-        let hix = head & (self.mark_bit - 1);
-        let tix = tail & (self.mark_bit - 1);
+            let hix = head & (self.mark_bit - 1);
+            let tix = tail & (self.mark_bit - 1);
 
-        let len = if hix < tix {
-            tix - hix
-        } else if hix > tix {
-            self.cap - hix + tix
-        } else if (tail & !self.mark_bit) == head {
-            0
-        } else {
-            self.cap
-        };
-
-        // Loop over all slots that hold a message and drop them.
-        for i in 0..len {
-            // Compute the index of the next slot holding a message.
-            let index = if hix + i < self.cap {
-                hix + i
+            let len = if hix < tix {
+                tix - hix
+            } else if hix > tix {
+                self.cap - hix + tix
+            } else if (tail & !self.mark_bit) == head {
+                0
             } else {
-                hix + i - self.cap
+                self.cap
             };
 
-            unsafe {
-                debug_assert!(index < self.buffer.len());
-                let slot = self.buffer.get_unchecked_mut(index);
-                let msg = &mut *slot.msg.get();
-                msg.as_mut_ptr().drop_in_place();
+            // Loop over all slots that hold a message and drop them.
+            for i in 0..len {
+                // Compute the index of the next slot holding a message.
+                let index = if hix + i < self.cap {
+                    hix + i
+                } else {
+                    hix + i - self.cap
+                };
+
+                unsafe {
+                    debug_assert!(index < self.buffer.len());
+                    let slot = self.buffer.get_unchecked_mut(index);
+                    (*slot.msg.get()).assume_init_drop();
+                }
             }
         }
     }
diff --git a/src/flavors/list.rs b/src/flavors/list.rs
index 6090b8d..638d6c2 100644
--- a/src/flavors/list.rs
+++ b/src/flavors/list.rs
@@ -584,6 +584,17 @@
         let mut head = self.head.index.load(Ordering::Acquire);
         let mut block = self.head.block.load(Ordering::Acquire);
 
+        // If we're going to be dropping messages we need to synchronize with initialization
+        if head >> SHIFT != tail >> SHIFT {
+            // The block can be null here only if a sender is in the process of initializing the
+            // channel while another sender managed to send a message by inserting it into the
+            // semi-initialized channel and advanced the tail.
+            // In that case, just wait until it gets initialized.
+            while block.is_null() {
+                backoff.snooze();
+                block = self.head.block.load(Ordering::Acquire);
+            }
+        }
         unsafe {
             // Drop all messages between head and tail and deallocate the heap-allocated blocks.
             while head >> SHIFT != tail >> SHIFT {
@@ -593,8 +604,7 @@
                     // Drop the message in the slot.
                     let slot = (*block).slots.get_unchecked(offset);
                     slot.wait_write();
-                    let p = &mut *slot.msg.get();
-                    p.as_mut_ptr().drop_in_place();
+                    (*slot.msg.get()).assume_init_drop();
                 } else {
                     (*block).wait_next();
                     // Deallocate the block and move to the next one.
@@ -652,8 +662,7 @@
                 if offset < BLOCK_CAP {
                     // Drop the message in the slot.
                     let slot = (*block).slots.get_unchecked(offset);
-                    let p = &mut *slot.msg.get();
-                    p.as_mut_ptr().drop_in_place();
+                    (*slot.msg.get()).assume_init_drop();
                 } else {
                     // Deallocate the block and move to the next one.
                     let next = *(*block).next.get_mut();
diff --git a/src/lib.rs b/src/lib.rs
index cc1ef11..0bb98a2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -336,36 +336,40 @@
 )]
 #![cfg_attr(not(feature = "std"), no_std)]
 
-use cfg_if::cfg_if;
+#[cfg(feature = "std")]
+mod channel;
+#[cfg(feature = "std")]
+mod context;
+#[cfg(feature = "std")]
+mod counter;
+#[cfg(feature = "std")]
+mod err;
+#[cfg(feature = "std")]
+mod flavors;
+#[cfg(feature = "std")]
+mod select;
+#[cfg(feature = "std")]
+mod select_macro;
+#[cfg(feature = "std")]
+mod utils;
+#[cfg(feature = "std")]
+mod waker;
 
-cfg_if! {
-    if #[cfg(feature = "std")] {
-        mod channel;
-        mod context;
-        mod counter;
-        mod err;
-        mod flavors;
-        mod select;
-        mod select_macro;
-        mod utils;
-        mod waker;
-
-        /// Crate internals used by the `select!` macro.
-        #[doc(hidden)]
-        pub mod internal {
-            pub use crate::select::SelectHandle;
-            pub use crate::select::{select, select_timeout, try_select};
-        }
-
-        pub use crate::channel::{after, at, never, tick};
-        pub use crate::channel::{bounded, unbounded};
-        pub use crate::channel::{IntoIter, Iter, TryIter};
-        pub use crate::channel::{Receiver, Sender};
-
-        pub use crate::select::{Select, SelectedOperation};
-
-        pub use crate::err::{ReadyTimeoutError, SelectTimeoutError, TryReadyError, TrySelectError};
-        pub use crate::err::{RecvError, RecvTimeoutError, TryRecvError};
-        pub use crate::err::{SendError, SendTimeoutError, TrySendError};
-    }
+/// Crate internals used by the `select!` macro.
+#[doc(hidden)]
+#[cfg(feature = "std")]
+pub mod internal {
+    pub use crate::select::{select, select_timeout, try_select, SelectHandle};
 }
+
+#[cfg(feature = "std")]
+pub use crate::{
+    channel::{
+        after, at, bounded, never, tick, unbounded, IntoIter, Iter, Receiver, Sender, TryIter,
+    },
+    err::{
+        ReadyTimeoutError, RecvError, RecvTimeoutError, SelectTimeoutError, SendError,
+        SendTimeoutError, TryReadyError, TryRecvError, TrySelectError, TrySendError,
+    },
+    select::{Select, SelectedOperation},
+};
diff --git a/src/select_macro.rs b/src/select_macro.rs
index efe0ae4..43932a6 100644
--- a/src/select_macro.rs
+++ b/src/select_macro.rs
@@ -685,7 +685,7 @@
         $default:tt
     ) => {{
         const _LEN: usize = $crate::crossbeam_channel_internal!(@count ($($cases)*));
-        let _handle: &$crate::internal::SelectHandle = &$crate::never::<()>();
+        let _handle: &dyn $crate::internal::SelectHandle = &$crate::never::<()>();
 
         #[allow(unused_mut)]
         let mut _sel = [(_handle, 0, ::std::ptr::null()); _LEN];
diff --git a/src/utils.rs b/src/utils.rs
index f623f27..705ca1a 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -13,7 +13,7 @@
     }
 
     thread_local! {
-        static RNG: Cell<Wrapping<u32>> = Cell::new(Wrapping(1_406_868_647));
+        static RNG: Cell<Wrapping<u32>> = const { Cell::new(Wrapping(1_406_868_647)) };
     }
 
     let _ = RNG.try_with(|rng| {
diff --git a/tests/mpsc.rs b/tests/mpsc.rs
index d7cc8e2..0cea233 100644
--- a/tests/mpsc.rs
+++ b/tests/mpsc.rs
@@ -20,11 +20,7 @@
 //!   - https://github.com/rust-lang/rust/blob/master/COPYRIGHT
 //!   - https://www.rust-lang.org/en-US/legal.html
 
-#![allow(
-    clippy::drop_copy,
-    clippy::match_single_binding,
-    clippy::redundant_clone
-)]
+#![allow(clippy::match_single_binding, clippy::redundant_clone)]
 
 use std::sync::mpsc::{RecvError, RecvTimeoutError, TryRecvError};
 use std::sync::mpsc::{SendError, TrySendError};
diff --git a/tests/ready.rs b/tests/ready.rs
index 6e3fb2b..ca84f86 100644
--- a/tests/ready.rs
+++ b/tests/ready.rs
@@ -1,7 +1,5 @@
 //! Tests for channel readiness using the `Select` struct.
 
-#![allow(clippy::drop_copy)]
-
 use std::any::Any;
 use std::cell::Cell;
 use std::thread;
diff --git a/tests/select.rs b/tests/select.rs
index bc5824d..3817840 100644
--- a/tests/select.rs
+++ b/tests/select.rs
@@ -1,7 +1,5 @@
 //! Tests for channel selection using the `Select` struct.
 
-#![allow(clippy::drop_copy)]
-
 use std::any::Any;
 use std::cell::Cell;
 use std::thread;
diff --git a/tests/select_macro.rs b/tests/select_macro.rs
index 119454c..c480809 100644
--- a/tests/select_macro.rs
+++ b/tests/select_macro.rs
@@ -1,7 +1,7 @@
 //! Tests for the `select!` macro.
 
 #![forbid(unsafe_code)] // select! is safe.
-#![allow(clippy::drop_copy, clippy::match_single_binding)]
+#![allow(clippy::match_single_binding)]
 
 use std::any::Any;
 use std::cell::Cell;
@@ -1212,32 +1212,32 @@
     let (_, r) = bounded::<i32>(0);
 
     select! {
-        recv(r) -> res => drop::<Result<i32, RecvError>>(res),
+        recv(r) -> res => { let _: Result<i32, RecvError> = res; },
     }
     select! {
-        recv(r) -> res => drop::<Result<i32, RecvError>>(res),
+        recv(r) -> res =>  { let _: Result<i32, RecvError> = res; },
         default => {}
     }
     select! {
-        recv(r) -> res => drop::<Result<i32, RecvError>>(res),
+        recv(r) -> res =>  { let _: Result<i32, RecvError> = res; },
         default(ms(0)) => {}
     }
 
     select! {
-        send(s, 0) -> res => drop::<Result<(), SendError<i32>>>(res),
+        send(s, 0) -> res => { let _: Result<(), SendError<i32>> = res; },
     }
     select! {
-        send(s, 0) -> res => drop::<Result<(), SendError<i32>>>(res),
+        send(s, 0) -> res =>  { let _: Result<(), SendError<i32>> = res; },
         default => {}
     }
     select! {
-        send(s, 0) -> res => drop::<Result<(), SendError<i32>>>(res),
+        send(s, 0) -> res =>  { let _: Result<(), SendError<i32>> = res; },
         default(ms(0)) => {}
     }
 
     select! {
-        send(s, 0) -> res => drop::<Result<(), SendError<i32>>>(res),
-        recv(r) -> res => drop::<Result<i32, RecvError>>(res),
+        send(s, 0) -> res =>  { let _: Result<(), SendError<i32>> = res; },
+        recv(r) -> res => { let _: Result<i32, RecvError> = res; },
     }
 }
 
diff --git a/tests/thread_locals.rs b/tests/thread_locals.rs
index fb4e577..4639833 100644
--- a/tests/thread_locals.rs
+++ b/tests/thread_locals.rs
@@ -30,7 +30,7 @@
     }
 
     thread_local! {
-        static FOO: Foo = Foo;
+        static FOO: Foo = const { Foo };
     }
 
     let (s, r) = unbounded::<()>();