You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asyncband.apache.org by ti...@apache.org on 2026/09/04 06:08:22 UTC

(asyncband) branch codex/audit-third-party-provenance updated: refactor: isolate third-party blocking executor

This is an automated email from the ASF dual-hosted git repository.

tisonkun pushed a commit to branch codex/audit-third-party-provenance
in repository https://gitbox.apache.org/repos/asf/asyncband.git


The following commit(s) were added to refs/heads/codex/audit-third-party-provenance by this push:
     new 1531f64  refactor: isolate third-party blocking executor
1531f64 is described below

commit 1531f64b830d988f7c6d98730c78db680c21a51e
Author: tison <wa...@gmail.com>
AuthorDate: Fri Sep 4 14:08:18 2026 +0800

    refactor: isolate third-party blocking executor
---
 LICENSE                            |  8 ++--
 asyncband/src/blocking/executor.rs | 89 ++++++++++++++++++++++++++++++++++++++
 asyncband/src/blocking/mod.rs      | 83 ++---------------------------------
 licenserc.toml                     |  1 +
 4 files changed, 97 insertions(+), 84 deletions(-)

diff --git a/LICENSE b/LICENSE
index d5c0249..9b8ef17 100644
--- a/LICENSE
+++ b/LICENSE
@@ -373,14 +373,14 @@ the following copyright notices:
   Copyright (c) 2016 Alex Crichton
   Copyright (c) 2017 The Tokio Authors
 
-The polling loop in asyncband/src/blocking/mod.rs is adapted from Pollster
+The polling loop in asyncband/src/blocking/executor.rs is adapted from Pollster
 1.0.1 at the following exact revision and source path:
 
   https://github.com/zesterer/pollster/blob/6a1a148208326e9c5b231b16f199f5227c550774/src/lib.rs
 
-Its reuse of a thread-local Parker/Waker pair, with a fresh pair for recursive
-calls, is adapted from futures-lite 2.6.1 at the following exact revision and
-source path:
+The same file's reuse of a thread-local Parker/Waker pair, with a fresh pair
+for recursive calls, is adapted from futures-lite 2.6.1 at the following exact
+revision and source path:
 
   https://github.com/smol-rs/futures-lite/blob/226ce18976d8714d6bd9700b61dcc81d7200bc9a/src/future.rs#L62-L91
 
diff --git a/asyncband/src/blocking/executor.rs b/asyncband/src/blocking/executor.rs
new file mode 100644
index 0000000..0a9c1e2
--- /dev/null
+++ b/asyncband/src/blocking/executor.rs
@@ -0,0 +1,89 @@
+// This file contains a polling loop adapted from Pollster 1.0.1 and a thread-local Parker/Waker
+// reuse strategy adapted from futures-lite 2.6.1.
+// Copyright (c) 2020-2021 Joshua Barretto
+// Asyncband uses the Apache-2.0 license option for code incorporated from both projects.
+// The incorporated code has been modified for use in Apache Asyncband.
+// Upstream sources:
+// https://github.com/zesterer/pollster/blob/6a1a148208326e9c5b231b16f199f5227c550774/src/lib.rs
+// https://github.com/smol-rs/futures-lite/blob/226ce18976d8714d6bd9700b61dcc81d7200bc9a/src/future.rs#L62-L91
+
+use std::cell::RefCell;
+use std::future::IntoFuture;
+use std::pin::pin;
+use std::task::Context;
+use std::task::Poll;
+use std::task::Waker;
+use std::time::Duration;
+use std::time::Instant;
+
+use super::parker::Parker;
+
+pub(super) fn block_on<F: IntoFuture>(future: F) -> F::Output {
+    let mut future = pin!(future.into_future());
+
+    with_parker(|parker, waker| {
+        let mut context = Context::from_waker(waker);
+
+        loop {
+            match future.as_mut().poll(&mut context) {
+                Poll::Pending => parker.park(),
+                Poll::Ready(output) => return output,
+            }
+        }
+    })
+}
+
+pub(super) fn wait_timeout<F: IntoFuture>(future: F, timeout: Duration) -> Option<F::Output> {
+    let Some(deadline) = Instant::now().checked_add(timeout) else {
+        // A duration beyond Instant's range cannot expire during the process lifetime.
+        return Some(block_on(future));
+    };
+    let mut future = pin!(future.into_future());
+
+    with_parker(|parker, waker| {
+        let mut context = Context::from_waker(waker);
+
+        loop {
+            if let Poll::Ready(output) = future.as_mut().poll(&mut context) {
+                return Some(output);
+            }
+
+            let now = Instant::now();
+            if now >= deadline {
+                return None;
+            }
+            parker.park_timeout(deadline.saturating_duration_since(now));
+        }
+    })
+}
+
+fn parker_and_waker() -> (Parker, Waker) {
+    let parker = Parker::new();
+    let waker = parker.waker();
+    (parker, waker)
+}
+
+thread_local! {
+    // Holding the mutable borrow while polling makes a recursive call take the fresh-parker path
+    // instead of sharing a notification token.
+    static CACHE: RefCell<(Parker, Waker)> = RefCell::new(parker_and_waker());
+}
+
+fn with_parker<T>(wait: impl FnOnce(&Parker, &Waker) -> T) -> T {
+    CACHE.with(|cache| {
+        let cached;
+        let fresh;
+        let (parker, waker) = match cache.try_borrow_mut() {
+            Ok(pair) => {
+                cached = pair;
+                &*cached
+            }
+            Err(_) => {
+                fresh = parker_and_waker();
+                &fresh
+            }
+        };
+
+        wait(parker, waker)
+    })
+}
diff --git a/asyncband/src/blocking/mod.rs b/asyncband/src/blocking/mod.rs
index eedce13..979714c 100644
--- a/asyncband/src/blocking/mod.rs
+++ b/asyncband/src/blocking/mod.rs
@@ -15,14 +15,6 @@
 // specific language governing permissions and limitations
 // under the License.
 
-// This file contains a polling loop adapted from Pollster 1.0.1 and a thread-local Parker/Waker
-// reuse strategy adapted from futures-lite 2.6.1.
-// Asyncband uses the Apache-2.0 license option for code incorporated from both projects.
-// The incorporated code has been modified for use in Apache Asyncband.
-// Upstream sources:
-// https://github.com/zesterer/pollster/blob/6a1a148208326e9c5b231b16f199f5227c550774/src/lib.rs
-// https://github.com/smol-rs/futures-lite/blob/226ce18976d8714d6bd9700b61dcc81d7200bc9a/src/future.rs#L62-L91
-
 //! Synchronous interoperability for runtime-agnostic futures.
 //!
 //! This module bridges synchronous Rust code to a single future. Enable it with the opt-in
@@ -62,18 +54,11 @@
 //! work assigned to that executor. Call these methods only from synchronous code, such as `main`,
 //! a dedicated thread, or a sync-to-async boundary.
 
+mod executor;
 mod parker;
 
-use std::cell::RefCell;
 use std::future::IntoFuture;
-use std::pin::pin;
-use std::task::Context;
-use std::task::Poll;
-use std::task::Waker;
 use std::time::Duration;
-use std::time::Instant;
-
-use self::parker::Parker;
 
 /// Extension methods for waiting on a future from synchronous code.
 ///
@@ -96,18 +81,7 @@ pub trait FutureExt: IntoFuture {
     where
         Self: Sized,
     {
-        let mut future = pin!(self.into_future());
-
-        with_parker(|parker, waker| {
-            let mut context = Context::from_waker(waker);
-
-            loop {
-                match future.as_mut().poll(&mut context) {
-                    Poll::Pending => parker.park(),
-                    Poll::Ready(output) => return output,
-                }
-            }
-        })
+        executor::block_on(self)
     }
 
     /// Blocks the current thread until this future is ready or `timeout` elapses.
@@ -123,59 +97,8 @@ pub trait FutureExt: IntoFuture {
     where
         Self: Sized,
     {
-        let Some(deadline) = Instant::now().checked_add(timeout) else {
-            // A duration beyond Instant's range cannot expire during the process lifetime.
-            return Some(FutureExt::block_on(self));
-        };
-        let mut future = pin!(self.into_future());
-
-        with_parker(|parker, waker| {
-            let mut context = Context::from_waker(waker);
-
-            loop {
-                if let Poll::Ready(output) = future.as_mut().poll(&mut context) {
-                    return Some(output);
-                }
-
-                let now = Instant::now();
-                if now >= deadline {
-                    return None;
-                }
-                parker.park_timeout(deadline.saturating_duration_since(now));
-            }
-        })
+        executor::wait_timeout(self, timeout)
     }
 }
 
 impl<F: IntoFuture> FutureExt for F {}
-
-fn parker_and_waker() -> (Parker, Waker) {
-    let parker = Parker::new();
-    let waker = parker.waker();
-    (parker, waker)
-}
-
-thread_local! {
-    // Holding the mutable borrow while polling makes a recursive call take the fresh-parker path
-    // instead of sharing a notification token.
-    static CACHE: RefCell<(Parker, Waker)> = RefCell::new(parker_and_waker());
-}
-
-fn with_parker<T>(wait: impl FnOnce(&Parker, &Waker) -> T) -> T {
-    CACHE.with(|cache| {
-        let cached;
-        let fresh;
-        let (parker, waker) = match cache.try_borrow_mut() {
-            Ok(pair) => {
-                cached = pair;
-                &*cached
-            }
-            Err(_) => {
-                fresh = parker_and_waker();
-                &fresh
-            }
-        };
-
-        wait(parker, waker)
-    })
-}
diff --git a/licenserc.toml b/licenserc.toml
index f59e715..f004664 100644
--- a/licenserc.toml
+++ b/licenserc.toml
@@ -22,6 +22,7 @@ builtin = "Apache-2.0-ASF"
 # These third-party-derived files use the applicable upstream license and copyright notices instead
 # of the standard ASF source header.
 excludes = [
+  "asyncband/src/blocking/executor.rs",
   "asyncband/src/blocking/parker.rs",
   "asyncband/src/mutex/mod.rs",
   "asyncband/src/pool/bounded.rs",


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@asyncband.apache.org
For additional commands, e-mail: commits-help@asyncband.apache.org