Snap for 10453563 from 4a6abca8da952da053a9642391c284d54cd512d8 to mainline-ipsec-release

Change-Id: I3b573c350e523c59ad4649c2d7a551d5b0c597b4
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index deccf0d..3fade60 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
 {
   "git": {
-    "sha1": "fc1e3250219170e31cddb8857a276cba7dd08d44"
+    "sha1": "5e3693a350f96244151081d2c030208cd15f9572"
   },
   "path_in_vcs": "futures-channel"
 }
\ No newline at end of file
diff --git a/Android.bp b/Android.bp
index c7bc955..c1c089d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -41,27 +41,134 @@
     ],
 }
 
+rust_test {
+    name: "futures-channel_test_src_lib",
+    host_supported: true,
+    crate_name: "futures_channel",
+    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: [
+        "alloc",
+        "default",
+        "futures-sink",
+        "sink",
+        "std",
+    ],
+    rustlibs: [
+        "libfutures",
+        "libfutures_core",
+        "libfutures_sink",
+        "libfutures_test",
+    ],
+}
+
+rust_defaults {
+    name: "futures-channel_test_defaults",
+    crate_name: "futures_channel",
+    cargo_env_compat: true,
+    cargo_pkg_version: "0.3.26",
+    test_suites: ["general-tests"],
+    auto_gen_config: 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_channel",
+    defaults: ["futures-channel_test_defaults"],
+    host_supported: true,
+    srcs: ["tests/channel.rs"],
+    test_options: {
+        unit_test: true,
+    },
+}
+
+rust_test {
+    name: "futures-channel_test_tests_mpsc-close",
+    defaults: ["futures-channel_test_defaults"],
+    host_supported: true,
+    srcs: ["tests/mpsc-close.rs"],
+    test_options: {
+        unit_test: true,
+    },
+}
+
+rust_test {
+    name: "futures-channel_test_tests_mpsc-size_hint",
+    defaults: ["futures-channel_test_defaults"],
+    host_supported: true,
+    srcs: ["tests/mpsc-size_hint.rs"],
+    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,
+    },
+}
+
+rust_test {
+    name: "futures-channel_test_tests_oneshot",
+    defaults: ["futures-channel_test_defaults"],
+    host_supported: true,
+    srcs: ["tests/oneshot.rs"],
+    test_options: {
+        unit_test: true,
+    },
+}
+
 rust_library {
     name: "libfutures_channel",
     host_supported: true,
     crate_name: "futures_channel",
     cargo_env_compat: true,
-    cargo_pkg_version: "0.3.21",
+    cargo_pkg_version: "0.3.26",
     srcs: ["src/lib.rs"],
     edition: "2018",
     features: [
         "alloc",
         "default",
+        "futures-sink",
+        "sink",
         "std",
     ],
     rustlibs: [
         "libfutures_core",
+        "libfutures_sink",
     ],
     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 d0a13f6..869d735 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,11 +13,12 @@
 edition = "2018"
 rust-version = "1.45"
 name = "futures-channel"
-version = "0.3.21"
+version = "0.3.26"
 description = """
 Channels for asynchronous communication using futures-rs.
 """
 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,17 @@
 ]
 
 [dependencies.futures-core]
-version = "0.3.21"
+version = "0.3.26"
 default-features = false
 
 [dependencies.futures-sink]
-version = "0.3.21"
+version = "0.3.26"
 optional = true
 default-features = false
 
 [dev-dependencies]
+futures = "0.3.21"
+futures-test = "0.3.21"
 
 [features]
 alloc = ["futures-core/alloc"]
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index f356eab..753fd46 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
 [package]
 name = "futures-channel"
-version = "0.3.21"
+version = "0.3.26"
 edition = "2018"
 rust-version = "1.45"
 license = "MIT OR Apache-2.0"
@@ -22,8 +22,8 @@
 cfg-target-has-atomic = []
 
 [dependencies]
-futures-core = { path = "../futures-core", version = "0.3.21", default-features = false }
-futures-sink = { path = "../futures-sink", version = "0.3.21", default-features = false, optional = true }
+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 }
 
 [dev-dependencies]
 futures = { path = "../futures", default-features = true }
diff --git a/METADATA b/METADATA
index 29bf06e..66ed9e7 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-channel
+# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
+
 name: "futures-channel"
 description: "Channels for asynchronous communication using futures-rs."
 third_party {
@@ -7,13 +11,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/futures-channel/futures-channel-0.3.21.crate"
+    value: "https://static.crates.io/crates/futures-channel/futures-channel-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 5ef61de..e24ae4b 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -5,6 +5,15 @@
       "path": "external/rust/crates/anyhow"
     },
     {
+      "path": "external/rust/crates/async-stream"
+    },
+    {
+      "path": "external/rust/crates/futures-executor"
+    },
+    {
+      "path": "external/rust/crates/futures-test"
+    },
+    {
       "path": "external/rust/crates/futures-util"
     },
     {
@@ -12,34 +21,58 @@
     },
     {
       "path": "external/rust/crates/tokio-test"
+    },
+    {
+      "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-channel_test_src_lib"
     },
     {
-      "name": "authfs_device_test_src_lib"
+      "name": "futures-channel_test_tests_channel"
     },
     {
-      "name": "doh_unit_test"
+      "name": "futures-channel_test_tests_mpsc"
     },
     {
-      "name": "virtualizationservice_device_test"
+      "name": "futures-channel_test_tests_mpsc-close"
+    },
+    {
+      "name": "futures-channel_test_tests_oneshot"
     }
   ],
   "presubmit-rust": [
     {
-      "name": "ZipFuseTest"
+      "name": "futures-channel_test_src_lib"
     },
     {
-      "name": "authfs_device_test_src_lib"
+      "name": "futures-channel_test_tests_channel"
     },
     {
-      "name": "doh_unit_test"
+      "name": "futures-channel_test_tests_mpsc"
     },
     {
-      "name": "virtualizationservice_device_test"
+      "name": "futures-channel_test_tests_mpsc-close"
+    },
+    {
+      "name": "futures-channel_test_tests_oneshot"
     }
   ]
 }
diff --git a/cargo2android.json b/cargo2android.json
index a7e2a4b..4458799 100644
--- a/cargo2android.json
+++ b/cargo2android.json
@@ -1,12 +1,14 @@
 {
   "apex-available": [
     "//apex_available:platform",
-    "com.android.bluetooth",
+    "com.android.btservices",
     "com.android.resolv",
     "com.android.virt"
   ],
   "dependencies": true,
   "device": true,
+  "features": "alloc,default,std,sink",
   "min-sdk-version": "29",
-  "run": true
+  "run": true,
+  "tests": true
 }
diff --git a/no_atomic_cas.rs b/no_atomic_cas.rs
index 9b05d4b..16ec628 100644
--- a/no_atomic_cas.rs
+++ b/no_atomic_cas.rs
@@ -2,12 +2,16 @@
 // 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/patches/Cargo.toml.patch b/patches/Cargo.toml.patch
new file mode 100644
index 0000000..d1da570
--- /dev/null
+++ b/patches/Cargo.toml.patch
@@ -0,0 +1,13 @@
+diff --git a/Cargo.toml b/Cargo.toml
+index d0a13f6..66f5639 100644
+--- a/Cargo.toml
++++ b/Cargo.toml
+@@ -38,6 +38,8 @@ optional = true
+ default-features = false
+ 
+ [dev-dependencies]
++futures = "0.3.21"
++futures-test = "0.3.21"
+ 
+ [features]
+ alloc = ["futures-core/alloc"]
diff --git a/src/mpsc/mod.rs b/src/mpsc/mod.rs
index 44834b7..cf45fe7 100644
--- a/src/mpsc/mod.rs
+++ b/src/mpsc/mod.rs
@@ -94,13 +94,11 @@
 #[cfg(feature = "sink")]
 mod sink_impl;
 
-#[derive(Debug)]
 struct UnboundedSenderInner<T> {
     // Channel state shared between the sender and receiver.
     inner: Arc<UnboundedInner<T>>,
 }
 
-#[derive(Debug)]
 struct BoundedSenderInner<T> {
     // Channel state shared between the sender and receiver.
     inner: Arc<BoundedInner<T>>,
@@ -122,13 +120,11 @@
 /// The transmission end of a bounded mpsc channel.
 ///
 /// This value is created by the [`channel`](channel) function.
-#[derive(Debug)]
 pub struct Sender<T>(Option<BoundedSenderInner<T>>);
 
 /// The transmission end of an unbounded mpsc channel.
 ///
 /// This value is created by the [`unbounded`](unbounded) function.
-#[derive(Debug)]
 pub struct UnboundedSender<T>(Option<UnboundedSenderInner<T>>);
 
 trait AssertKinds: Send + Sync + Clone {}
@@ -137,7 +133,6 @@
 /// The receiving end of a bounded mpsc channel.
 ///
 /// This value is created by the [`channel`](channel) function.
-#[derive(Debug)]
 pub struct Receiver<T> {
     inner: Option<Arc<BoundedInner<T>>>,
 }
@@ -145,7 +140,6 @@
 /// The receiving end of an unbounded mpsc channel.
 ///
 /// This value is created by the [`unbounded`](unbounded) function.
-#[derive(Debug)]
 pub struct UnboundedReceiver<T> {
     inner: Option<Arc<UnboundedInner<T>>>,
 }
@@ -261,7 +255,6 @@
 
 impl std::error::Error for TryRecvError {}
 
-#[derive(Debug)]
 struct UnboundedInner<T> {
     // Internal channel state. Consists of the number of messages stored in the
     // channel as well as a flag signalling that the channel is closed.
@@ -277,7 +270,6 @@
     recv_task: AtomicWaker,
 }
 
-#[derive(Debug)]
 struct BoundedInner<T> {
     // Max buffer size of the channel. If `None` then the channel is unbounded.
     buffer: usize,
@@ -300,7 +292,7 @@
 }
 
 // Struct representation of `Inner::state`.
-#[derive(Debug, Clone, Copy)]
+#[derive(Clone, Copy)]
 struct State {
     // `true` when the channel is open
     is_open: bool,
@@ -324,7 +316,6 @@
 const MAX_BUFFER: usize = MAX_CAPACITY >> 1;
 
 // Sent to the consumer to wake up blocked producers
-#[derive(Debug)]
 struct SenderTask {
     task: Option<Waker>,
     is_parked: bool,
@@ -947,6 +938,18 @@
     }
 }
 
+impl<T> fmt::Debug for Sender<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("Sender").field("closed", &self.is_closed()).finish()
+    }
+}
+
+impl<T> fmt::Debug for UnboundedSender<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("UnboundedSender").field("closed", &self.is_closed()).finish()
+    }
+}
+
 /*
  *
  * ===== impl Receiver =====
@@ -1075,6 +1078,14 @@
             }
         }
     }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        if let Some(inner) = &self.inner {
+            decode_state(inner.state.load(SeqCst)).size_hint()
+        } else {
+            (0, Some(0))
+        }
+    }
 }
 
 impl<T> Drop for Receiver<T> {
@@ -1107,6 +1118,18 @@
     }
 }
 
+impl<T> fmt::Debug for Receiver<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let closed = if let Some(ref inner) = self.inner {
+            decode_state(inner.state.load(SeqCst)).is_closed()
+        } else {
+            false
+        };
+
+        f.debug_struct("Receiver").field("closed", &closed).finish()
+    }
+}
+
 impl<T> UnboundedReceiver<T> {
     /// Closes the receiving half of a channel, without dropping it.
     ///
@@ -1207,6 +1230,14 @@
             }
         }
     }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        if let Some(inner) = &self.inner {
+            decode_state(inner.state.load(SeqCst)).size_hint()
+        } else {
+            (0, Some(0))
+        }
+    }
 }
 
 impl<T> Drop for UnboundedReceiver<T> {
@@ -1239,6 +1270,18 @@
     }
 }
 
+impl<T> fmt::Debug for UnboundedReceiver<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let closed = if let Some(ref inner) = self.inner {
+            decode_state(inner.state.load(SeqCst)).is_closed()
+        } else {
+            false
+        };
+
+        f.debug_struct("Receiver").field("closed", &closed).finish()
+    }
+}
+
 /*
  *
  * ===== impl Inner =====
@@ -1285,6 +1328,14 @@
     fn is_closed(&self) -> bool {
         !self.is_open && self.num_messages == 0
     }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        if self.is_open {
+            (self.num_messages, None)
+        } else {
+            (self.num_messages, Some(self.num_messages))
+        }
+    }
 }
 
 /*
diff --git a/src/mpsc/queue.rs b/src/mpsc/queue.rs
index 57dc7f5..02ec633 100644
--- a/src/mpsc/queue.rs
+++ b/src/mpsc/queue.rs
@@ -61,7 +61,6 @@
     Inconsistent,
 }
 
-#[derive(Debug)]
 struct Node<T> {
     next: AtomicPtr<Self>,
     value: Option<T>,
@@ -70,7 +69,6 @@
 /// The multi-producer single-consumer structure. This is not cloneable, but it
 /// may be safely shared so long as it is guaranteed that there is only one
 /// popper at a time (many pushers are allowed).
-#[derive(Debug)]
 pub(super) struct Queue<T> {
     head: AtomicPtr<Node<T>>,
     tail: UnsafeCell<*mut Node<T>>,
diff --git a/src/oneshot.rs b/src/oneshot.rs
index 5af651b..70449f4 100644
--- a/src/oneshot.rs
+++ b/src/oneshot.rs
@@ -390,7 +390,7 @@
     }
 }
 
-impl<T: fmt::Debug> fmt::Debug for Sender<T> {
+impl<T> fmt::Debug for Sender<T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("Sender").field("complete", &self.inner.complete).finish()
     }
@@ -481,7 +481,7 @@
     }
 }
 
-impl<T: fmt::Debug> fmt::Debug for Receiver<T> {
+impl<T> fmt::Debug for Receiver<T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("Receiver").field("complete", &self.inner.complete).finish()
     }
diff --git a/tests/mpsc-size_hint.rs b/tests/mpsc-size_hint.rs
new file mode 100644
index 0000000..d9cdaa3
--- /dev/null
+++ b/tests/mpsc-size_hint.rs
@@ -0,0 +1,40 @@
+use futures::channel::mpsc;
+use futures::stream::Stream;
+
+#[test]
+fn unbounded_size_hint() {
+    let (tx, mut rx) = mpsc::unbounded::<u32>();
+    assert_eq!((0, None), rx.size_hint());
+    tx.unbounded_send(1).unwrap();
+    assert_eq!((1, None), rx.size_hint());
+    rx.try_next().unwrap().unwrap();
+    assert_eq!((0, None), rx.size_hint());
+    tx.unbounded_send(2).unwrap();
+    tx.unbounded_send(3).unwrap();
+    assert_eq!((2, None), rx.size_hint());
+    drop(tx);
+    assert_eq!((2, Some(2)), rx.size_hint());
+    rx.try_next().unwrap().unwrap();
+    assert_eq!((1, Some(1)), rx.size_hint());
+    rx.try_next().unwrap().unwrap();
+    assert_eq!((0, Some(0)), rx.size_hint());
+}
+
+#[test]
+fn channel_size_hint() {
+    let (mut tx, mut rx) = mpsc::channel::<u32>(10);
+    assert_eq!((0, None), rx.size_hint());
+    tx.try_send(1).unwrap();
+    assert_eq!((1, None), rx.size_hint());
+    rx.try_next().unwrap().unwrap();
+    assert_eq!((0, None), rx.size_hint());
+    tx.try_send(2).unwrap();
+    tx.try_send(3).unwrap();
+    assert_eq!((2, None), rx.size_hint());
+    drop(tx);
+    assert_eq!((2, Some(2)), rx.size_hint());
+    rx.try_next().unwrap().unwrap();
+    assert_eq!((1, Some(1)), rx.size_hint());
+    rx.try_next().unwrap().unwrap();
+    assert_eq!((0, Some(0)), rx.size_hint());
+}
diff --git a/tests/mpsc.rs b/tests/mpsc.rs
index da0899d..444c8e1 100644
--- a/tests/mpsc.rs
+++ b/tests/mpsc.rs
@@ -200,10 +200,7 @@
 
 #[test]
 fn stress_shared_unbounded() {
-    #[cfg(miri)]
-    const AMT: u32 = 100;
-    #[cfg(not(miri))]
-    const AMT: u32 = 10000;
+    const AMT: u32 = if cfg!(miri) { 100 } else { 10000 };
     const NTHREADS: u32 = 8;
     let (tx, rx) = mpsc::unbounded::<i32>();
 
@@ -232,10 +229,7 @@
 
 #[test]
 fn stress_shared_bounded_hard() {
-    #[cfg(miri)]
-    const AMT: u32 = 100;
-    #[cfg(not(miri))]
-    const AMT: u32 = 10000;
+    const AMT: u32 = if cfg!(miri) { 100 } else { 10000 };
     const NTHREADS: u32 = 8;
     let (tx, rx) = mpsc::channel::<i32>(0);
 
@@ -265,10 +259,7 @@
 #[allow(clippy::same_item_push)]
 #[test]
 fn stress_receiver_multi_task_bounded_hard() {
-    #[cfg(miri)]
-    const AMT: usize = 100;
-    #[cfg(not(miri))]
-    const AMT: usize = 10_000;
+    const AMT: usize = if cfg!(miri) { 100 } else { 10_000 };
     const NTHREADS: u32 = 2;
 
     let (mut tx, rx) = mpsc::channel::<usize>(0);
@@ -336,10 +327,7 @@
 /// after sender dropped.
 #[test]
 fn stress_drop_sender() {
-    #[cfg(miri)]
-    const ITER: usize = 100;
-    #[cfg(not(miri))]
-    const ITER: usize = 10000;
+    const ITER: usize = if cfg!(miri) { 100 } else { 10000 };
 
     fn list() -> impl Stream<Item = i32> {
         let (tx, rx) = mpsc::channel(1);
@@ -394,10 +382,9 @@
     }
 }
 
-#[cfg_attr(miri, ignore)] // Miri is too slow
 #[test]
 fn stress_close_receiver() {
-    const ITER: usize = 10000;
+    const ITER: usize = if cfg!(miri) { 50 } else { 10000 };
 
     for _ in 0..ITER {
         stress_close_receiver_iter();
@@ -414,10 +401,7 @@
 #[allow(clippy::same_item_push)]
 #[test]
 fn stress_poll_ready() {
-    #[cfg(miri)]
-    const AMT: u32 = 100;
-    #[cfg(not(miri))]
-    const AMT: u32 = 1000;
+    const AMT: u32 = if cfg!(miri) { 100 } else { 1000 };
     const NTHREADS: u32 = 8;
 
     /// Run a stress test using the specified channel capacity.
@@ -444,10 +428,9 @@
     stress(16);
 }
 
-#[cfg_attr(miri, ignore)] // Miri is too slow
 #[test]
 fn try_send_1() {
-    const N: usize = 3000;
+    const N: usize = if cfg!(miri) { 100 } else { 3000 };
     let (mut tx, rx) = mpsc::channel(0);
 
     let t = thread::spawn(move || {
diff --git a/tests/oneshot.rs b/tests/oneshot.rs
index c9f5508..6b48376 100644
--- a/tests/oneshot.rs
+++ b/tests/oneshot.rs
@@ -35,10 +35,7 @@
 
 #[test]
 fn cancel_lots() {
-    #[cfg(miri)]
-    const N: usize = 100;
-    #[cfg(not(miri))]
-    const N: usize = 20000;
+    const N: usize = if cfg!(miri) { 100 } else { 20000 };
 
     let (tx, rx) = mpsc::channel::<(Sender<_>, mpsc::Sender<_>)>();
     let t = thread::spawn(move || {
@@ -106,10 +103,7 @@
 
 #[test]
 fn cancel_sends() {
-    #[cfg(miri)]
-    const N: usize = 100;
-    #[cfg(not(miri))]
-    const N: usize = 20000;
+    const N: usize = if cfg!(miri) { 100 } else { 20000 };
 
     let (tx, rx) = mpsc::channel::<Sender<_>>();
     let t = thread::spawn(move || {