Snap for 8564071 from de861550982f984d861521fdde94390d4eb60003 to mainline-os-statsd-release

Change-Id: I4b7c0dc38b798d97d5992501251619f5c7e405ed
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
new file mode 100644
index 0000000..afec74b
--- /dev/null
+++ b/.cargo_vcs_info.json
@@ -0,0 +1,6 @@
+{
+  "git": {
+    "sha1": "e6daa4ff3caadb73c7a7ddc40034fb02430ccec8"
+  },
+  "path_in_vcs": ""
+}
\ No newline at end of file
diff --git a/.github/workflows/build-and-test.yaml b/.github/workflows/build-and-test.yaml
deleted file mode 100644
index d98cd81..0000000
--- a/.github/workflows/build-and-test.yaml
+++ /dev/null
@@ -1,50 +0,0 @@
-name: Build and test
-
-on:
-  push:
-    branches:
-      - master
-  pull_request:
-
-jobs:
-  build_and_test:
-    runs-on: ${{ matrix.os }}
-    strategy:
-      fail-fast: false
-      matrix:
-        os: [ubuntu-latest]
-        rust: [nightly, beta, stable]
-    steps:
-      - uses: actions/checkout@v2
-
-      - name: Install latest ${{ matrix.rust }}
-        uses: actions-rs/toolchain@v1
-        with:
-            toolchain: ${{ matrix.rust }}
-            profile: minimal
-            override: true
-
-      - name: Install valgrind
-        run: |
-          sudo apt-get update
-          sudo apt-get install -y valgrind
-
-      - name: Run cargo check
-        uses: actions-rs/cargo@v1
-        with:
-          command: check
-          args: --all --bins --examples --tests --all-features
-
-      - name: Run cargo check (no_std)
-        uses: actions-rs/cargo@v1
-        with:
-          command: check
-          args: --all --no-default-features
-
-      - name: Run cargo test
-        uses: actions-rs/cargo@v1
-        with:
-          command: test
-          args: -- --test-threads=1
-        env:
-          CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER: "valgrind --leak-check=full --error-exitcode=1"
diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml
deleted file mode 100644
index e134a54..0000000
--- a/.github/workflows/lint.yaml
+++ /dev/null
@@ -1,24 +0,0 @@
-name: Lint
-
-on:
-  push:
-    branches:
-      - master
-  pull_request:
-
-jobs:
-  clippy:
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v2
-
-      - uses: actions-rs/toolchain@v1
-        with:
-          toolchain: stable
-          profile: minimal
-          components: clippy
-
-      - uses: actions-rs/clippy-check@v1
-        with:
-          token: ${{ secrets.GITHUB_TOKEN }}
-          args: --all-features -- -W clippy::all
diff --git a/.github/workflows/security.yaml b/.github/workflows/security.yaml
deleted file mode 100644
index c4f7947..0000000
--- a/.github/workflows/security.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-name: Security audit
-
-on:
-  push:
-    branches:
-      - master
-  pull_request:
-
-jobs:
-  security_audit:
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v2
-
-      - uses: actions-rs/audit-check@v1
-        with:
-          token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/Android.bp b/Android.bp
index b1393c7..419d97d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,4 +1,5 @@
-// This file is generated by cargo2android.py --run.
+// This file is generated by cargo2android.py --config cargo2android.json.
+// Do not modify this file as changes will be overridden on upgrade.
 
 package {
     default_applicable_licenses: ["external_rust_crates_async-task_license"],
@@ -38,16 +39,18 @@
 
 rust_library {
     name: "libasync_task",
+    host_supported: true,
     crate_name: "async_task",
+    cargo_env_compat: true,
+    cargo_pkg_version: "4.1.0",
     srcs: ["src/lib.rs"],
     edition: "2018",
-    host_supported: true,
     features: [
         "default",
         "std",
     ],
     apex_available: [
         "//apex_available:platform",
-	"com.android.virt",
+        "com.android.virt",
     ],
 }
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6bdcc73..668bd12 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# Version 4.1.0
+
+- Add `FallibleTask`. (#21)
+
 # Version 4.0.3
 
 - Document the return value of `Runnable::run()` better.
diff --git a/Cargo.toml b/Cargo.toml
index c50b366..f563dc6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,23 +1,45 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
 [package]
-name = "async-task"
-version = "4.0.3"
-authors = ["Stjepan Glavina <stjepang@gmail.com>"]
 edition = "2018"
-license = "Apache-2.0 OR MIT"
-repository = "https://github.com/smol-rs/async-task"
-homepage = "https://github.com/smol-rs/async-task"
-documentation = "https://docs.rs/async-task"
+rust-version = "1.39"
+name = "async-task"
+version = "4.1.0"
+authors = ["Stjepan Glavina <stjepang@gmail.com>"]
+exclude = ["/.*"]
 description = "Task abstraction for building executors"
 keywords = ["futures", "task", "executor", "spawn"]
 categories = ["asynchronous", "concurrency", "no-std"]
+license = "Apache-2.0 OR MIT"
+repository = "https://github.com/smol-rs/async-task"
+[dev-dependencies.atomic-waker]
+version = "1"
+
+[dev-dependencies.easy-parallel]
+version = "3"
+
+[dev-dependencies.flaky_test]
+version = "0.1"
+
+[dev-dependencies.flume]
+version = "0.10"
+default-features = false
+
+[dev-dependencies.once_cell]
+version = "1"
+
+[dev-dependencies.smol]
+version = "1"
 
 [features]
 default = ["std"]
 std = []
-
-[dev-dependencies]
-atomic-waker = "1.0.0"
-easy-parallel = "3.1.0"
-flume = { version = "0.10", default-features = false }
-once_cell = "1.4.1"
-smol = "1.0.1"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
new file mode 100644
index 0000000..b1ae509
--- /dev/null
+++ b/Cargo.toml.orig
@@ -0,0 +1,31 @@
+[package]
+name = "async-task"
+# When publishing a new version:
+# - Update CHANGELOG.md
+# - Create "v4.x.y" git tag
+version = "4.1.0"
+authors = ["Stjepan Glavina <stjepang@gmail.com>"]
+edition = "2018"
+rust-version = "1.39"
+license = "Apache-2.0 OR MIT"
+repository = "https://github.com/smol-rs/async-task"
+description = "Task abstraction for building executors"
+keywords = ["futures", "task", "executor", "spawn"]
+categories = ["asynchronous", "concurrency", "no-std"]
+exclude = ["/.*"]
+
+[features]
+default = ["std"]
+std = []
+
+[dev-dependencies]
+atomic-waker = "1"
+easy-parallel = "3"
+flaky_test = "0.1"
+flume = { version = "0.10", default-features = false }
+once_cell = "1"
+smol = "1"
+
+# rewrite dependencies to use the this version of async-task when running tests
+[patch.crates-io]
+async-task = { path = "." }
diff --git a/METADATA b/METADATA
index 463f005..23c5a33 100644
--- a/METADATA
+++ b/METADATA
@@ -1,7 +1,5 @@
 name: "async_task"
-description:
-    "Task abstraction for building executors (in rust)."
-
+description: "Task abstraction for building executors"
 third_party {
   url {
     type: HOMEPAGE
@@ -9,9 +7,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/async-task/async-task-4.0.3.crate"
+    value: "https://static.crates.io/crates/async_task/async_task-4.1.0.crate"
   }
-  version: "4.0.3"
-  last_upgrade_date { year: 2021 month: 2 day: 5 }
+  version: "4.1.0"
   license_type: NOTICE
+  last_upgrade_date {
+    year: 2022
+    month: 3
+    day: 1
+  }
 }
diff --git a/TEST_MAPPING b/TEST_MAPPING
new file mode 100644
index 0000000..fc8ec65
--- /dev/null
+++ b/TEST_MAPPING
@@ -0,0 +1,25 @@
+// Generated by update_crate_tests.py for tests that depend on this crate.
+{
+  "presubmit": [
+    {
+      "name": "ZipFuseTest"
+    },
+    {
+      "name": "authfs_device_test_src_lib"
+    },
+    {
+      "name": "virtualizationservice_device_test"
+    }
+  ],
+  "presubmit-rust": [
+    {
+      "name": "ZipFuseTest"
+    },
+    {
+      "name": "authfs_device_test_src_lib"
+    },
+    {
+      "name": "virtualizationservice_device_test"
+    }
+  ]
+}
diff --git a/cargo2android.json b/cargo2android.json
new file mode 100644
index 0000000..707d26c
--- /dev/null
+++ b/cargo2android.json
@@ -0,0 +1,8 @@
+{
+  "apex-available": [
+    "//apex_available:platform",
+    "com.android.virt"
+  ],
+  "device": true,
+  "run": true
+}
\ No newline at end of file
diff --git a/src/lib.rs b/src/lib.rs
index 852696e..4a868bf 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -82,7 +82,7 @@
 mod utils;
 
 pub use crate::runnable::{spawn, spawn_unchecked, Runnable};
-pub use crate::task::Task;
+pub use crate::task::{FallibleTask, Task};
 
 #[cfg(feature = "std")]
 pub use crate::runnable::spawn_local;
diff --git a/src/runnable.rs b/src/runnable.rs
index adecbcb..cb70ef3 100644
--- a/src/runnable.rs
+++ b/src/runnable.rs
@@ -147,7 +147,7 @@
 /// This function is same as [`spawn()`], except it does not require [`Send`], [`Sync`], and
 /// `'static` on `future` and `schedule`.
 ///
-/// Safety requirements:
+/// # Safety
 ///
 /// - If `future` is not [`Send`], its [`Runnable`] must be used and dropped on the original
 ///   thread.
diff --git a/src/task.rs b/src/task.rs
index b9c251f..fff918c 100644
--- a/src/task.rs
+++ b/src/task.rs
@@ -124,18 +124,56 @@
     pub async fn cancel(self) -> Option<T> {
         let mut this = self;
         this.set_canceled();
+        this.fallible().await
+    }
 
-        struct Fut<T>(Task<T>);
-
-        impl<T> Future for Fut<T> {
-            type Output = Option<T>;
-
-            fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
-                self.0.poll_task(cx)
-            }
-        }
-
-        Fut(this).await
+    /// Converts this task into a [`FallibleTask`].
+    ///
+    /// Like [`Task`], a fallible task will poll the task's output until it is
+    /// completed or cancelled due to its [`Runnable`][`super::Runnable`] being
+    /// dropped without being run. Resolves to the task's output when completed,
+    /// or [`None`] if it didn't complete.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use smol::{future, Executor};
+    /// use std::thread;
+    ///
+    /// let ex = Executor::new();
+    ///
+    /// // Spawn a future onto the executor.
+    /// let task = ex.spawn(async {
+    ///     println!("Hello from a task!");
+    ///     1 + 2
+    /// })
+    /// .fallible();
+    ///
+    /// // Run an executor thread.
+    /// thread::spawn(move || future::block_on(ex.run(future::pending::<()>())));
+    ///
+    /// // Wait for the task's output.
+    /// assert_eq!(future::block_on(task), Some(3));
+    /// ```
+    ///
+    /// ```
+    /// use smol::future;
+    ///
+    /// // Schedule function which drops the runnable without running it.
+    /// let schedule = move |runnable| drop(runnable);
+    ///
+    /// // Create a task with the future and the schedule function.
+    /// let (runnable, task) = async_task::spawn(async {
+    ///     println!("Hello from a task!");
+    ///     1 + 2
+    /// }, schedule);
+    /// runnable.schedule();
+    ///
+    /// // Wait for the task's output.
+    /// assert_eq!(future::block_on(task.fallible()), None);
+    /// ```
+    pub fn fallible(self) -> FallibleTask<T> {
+        FallibleTask { task: self }
     }
 
     /// Puts the task in canceled state.
@@ -351,6 +389,12 @@
             }
         }
     }
+
+    fn header(&self) -> &Header {
+        let ptr = self.ptr.as_ptr();
+        let header = ptr as *const Header;
+        unsafe { &*header }
+    }
 }
 
 impl<T> Drop for Task<T> {
@@ -373,11 +417,101 @@
 
 impl<T> fmt::Debug for Task<T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let ptr = self.ptr.as_ptr();
-        let header = ptr as *const Header;
-
         f.debug_struct("Task")
-            .field("header", unsafe { &(*header) })
+            .field("header", self.header())
+            .finish()
+    }
+}
+
+/// A spawned task with a fallible response.
+///
+/// This type behaves like [`Task`], however it produces an `Option<T>` when
+/// polled and will return `None` if the executor dropped its
+/// [`Runnable`][`super::Runnable`] without being run.
+///
+/// This can be useful to avoid the panic produced when polling the `Task`
+/// future if the executor dropped its `Runnable`.
+#[must_use = "tasks get canceled when dropped, use `.detach()` to run them in the background"]
+pub struct FallibleTask<T> {
+    task: Task<T>,
+}
+
+impl<T> FallibleTask<T> {
+    /// Detaches the task to let it keep running in the background.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use smol::{Executor, Timer};
+    /// use std::time::Duration;
+    ///
+    /// let ex = Executor::new();
+    ///
+    /// // Spawn a deamon future.
+    /// ex.spawn(async {
+    ///     loop {
+    ///         println!("I'm a daemon task looping forever.");
+    ///         Timer::after(Duration::from_secs(1)).await;
+    ///     }
+    /// })
+    /// .fallible()
+    /// .detach();
+    /// ```
+    pub fn detach(self) {
+        self.task.detach()
+    }
+
+    /// Cancels the task and waits for it to stop running.
+    ///
+    /// Returns the task's output if it was completed just before it got canceled, or [`None`] if
+    /// it didn't complete.
+    ///
+    /// While it's possible to simply drop the [`Task`] to cancel it, this is a cleaner way of
+    /// canceling because it also waits for the task to stop running.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use smol::{future, Executor, Timer};
+    /// use std::thread;
+    /// use std::time::Duration;
+    ///
+    /// let ex = Executor::new();
+    ///
+    /// // Spawn a deamon future.
+    /// let task = ex.spawn(async {
+    ///     loop {
+    ///         println!("Even though I'm in an infinite loop, you can still cancel me!");
+    ///         Timer::after(Duration::from_secs(1)).await;
+    ///     }
+    /// })
+    /// .fallible();
+    ///
+    /// // Run an executor thread.
+    /// thread::spawn(move || future::block_on(ex.run(future::pending::<()>())));
+    ///
+    /// future::block_on(async {
+    ///     Timer::after(Duration::from_secs(3)).await;
+    ///     task.cancel().await;
+    /// });
+    /// ```
+    pub async fn cancel(self) -> Option<T> {
+        self.task.cancel().await
+    }
+}
+
+impl<T> Future for FallibleTask<T> {
+    type Output = Option<T>;
+
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        self.task.poll_task(cx)
+    }
+}
+
+impl<T> fmt::Debug for FallibleTask<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("FallibleTask")
+            .field("header", self.task.header())
             .finish()
     }
 }
diff --git a/tests/basic.rs b/tests/basic.rs
index 1439e16..c223043 100644
--- a/tests/basic.rs
+++ b/tests/basic.rs
@@ -64,7 +64,7 @@
 
             let guard = Guard(Box::new(0));
             move |_runnable| {
-                &guard;
+                let _ = &guard;
                 $sched.fetch_add(1, Ordering::SeqCst);
             }
         };
diff --git a/tests/cancel.rs b/tests/cancel.rs
index 4f77ae5..0fe7c72 100644
--- a/tests/cancel.rs
+++ b/tests/cancel.rs
@@ -81,7 +81,7 @@
 
             let guard = Guard(Box::new(0));
             move |runnable: Runnable| {
-                &guard;
+                let _ = &guard;
                 runnable.schedule();
                 $sched.fetch_add(1, Ordering::SeqCst);
             }
diff --git a/tests/join.rs b/tests/join.rs
index 17312a4..2ac7b8d 100644
--- a/tests/join.rs
+++ b/tests/join.rs
@@ -82,7 +82,7 @@
 
             let guard = Guard(Box::new(0));
             move |runnable: Runnable| {
-                &guard;
+                let _ = &guard;
                 runnable.schedule();
                 $sched.fetch_add(1, Ordering::SeqCst);
             }
diff --git a/tests/panic.rs b/tests/panic.rs
index f38fb3e..09ffb28 100644
--- a/tests/panic.rs
+++ b/tests/panic.rs
@@ -69,7 +69,7 @@
 
             let guard = Guard(Box::new(0));
             move |_runnable: Runnable| {
-                &guard;
+                let _ = &guard;
                 $sched.fetch_add(1, Ordering::SeqCst);
             }
         };
diff --git a/tests/ready.rs b/tests/ready.rs
index ebfdc63..e345565 100644
--- a/tests/ready.rs
+++ b/tests/ready.rs
@@ -81,7 +81,7 @@
 
             let guard = Guard(Box::new(0));
             move |_runnable: Runnable| {
-                &guard;
+                let _ = &guard;
                 $sched.fetch_add(1, Ordering::SeqCst);
             }
         };
diff --git a/tests/waker_panic.rs b/tests/waker_panic.rs
index 68b0a81..7a7792e 100644
--- a/tests/waker_panic.rs
+++ b/tests/waker_panic.rs
@@ -86,7 +86,7 @@
 
             let guard = Guard(Box::new(0));
             let sched = move |runnable: Runnable| {
-                &guard;
+                let _ = &guard;
                 $sched.fetch_add(1, Ordering::SeqCst);
                 s.send(runnable).unwrap();
             };
@@ -238,10 +238,15 @@
         .run();
 }
 
-#[test]
+#[flaky_test::flaky_test]
 fn cancel_and_wake_during_run() {
     future!(f, get_waker, POLL, DROP_F);
     schedule!(s, chan, SCHEDULE, DROP_S);
+    POLL.store(0, Ordering::SeqCst);
+    DROP_F.store(0, Ordering::SeqCst);
+    SCHEDULE.store(0, Ordering::SeqCst);
+    DROP_S.store(0, Ordering::SeqCst);
+
     let (runnable, task) = async_task::spawn(f, s);
 
     runnable.run();
diff --git a/tests/waker_pending.rs b/tests/waker_pending.rs
index e30af33..9c95cba 100644
--- a/tests/waker_pending.rs
+++ b/tests/waker_pending.rs
@@ -77,7 +77,7 @@
 
             let guard = Guard(Box::new(0));
             let sched = move |runnable: Runnable| {
-                &guard;
+                let _ = &guard;
                 $sched.fetch_add(1, Ordering::SeqCst);
                 s.send(runnable).unwrap();
             };
diff --git a/tests/waker_ready.rs b/tests/waker_ready.rs
index d46fd6f..10d38cb 100644
--- a/tests/waker_ready.rs
+++ b/tests/waker_ready.rs
@@ -83,7 +83,7 @@
 
             let guard = Guard(Box::new(0));
             let sched = move |runnable: Runnable| {
-                &guard;
+                let _ = &guard;
                 $sched.fetch_add(1, Ordering::SeqCst);
                 s.send(runnable).unwrap();
             };