wip: implemented incoming-like body for asynchronous operation in http/3
This commit is contained in:
parent
1dc88ce056
commit
4b6f63e09f
11 changed files with 376 additions and 68 deletions
67
rpxy-lib/src/hyper_ext/watch.rs
Normal file
67
rpxy-lib/src/hyper_ext/watch.rs
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
//! An SPSC broadcast channel.
|
||||
//!
|
||||
//! - The value can only be a `usize`.
|
||||
//! - The consumer is only notified if the value is different.
|
||||
//! - The value `0` is reserved for closed.
|
||||
// from https://github.com/hyperium/hyper/blob/master/src/common/watch.rs
|
||||
|
||||
use futures_util::task::AtomicWaker;
|
||||
use std::sync::{
|
||||
atomic::{AtomicUsize, Ordering},
|
||||
Arc,
|
||||
};
|
||||
use std::task;
|
||||
|
||||
type Value = usize;
|
||||
|
||||
pub(super) const CLOSED: usize = 0;
|
||||
|
||||
pub(super) fn channel(initial: Value) -> (Sender, Receiver) {
|
||||
debug_assert!(initial != CLOSED, "watch::channel initial state of 0 is reserved");
|
||||
|
||||
let shared = Arc::new(Shared {
|
||||
value: AtomicUsize::new(initial),
|
||||
waker: AtomicWaker::new(),
|
||||
});
|
||||
|
||||
(Sender { shared: shared.clone() }, Receiver { shared })
|
||||
}
|
||||
|
||||
pub(super) struct Sender {
|
||||
shared: Arc<Shared>,
|
||||
}
|
||||
|
||||
pub(super) struct Receiver {
|
||||
shared: Arc<Shared>,
|
||||
}
|
||||
|
||||
struct Shared {
|
||||
value: AtomicUsize,
|
||||
waker: AtomicWaker,
|
||||
}
|
||||
|
||||
impl Sender {
|
||||
pub(super) fn send(&mut self, value: Value) {
|
||||
if self.shared.value.swap(value, Ordering::SeqCst) != value {
|
||||
self.shared.waker.wake();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Sender {
|
||||
fn drop(&mut self) {
|
||||
self.send(CLOSED);
|
||||
}
|
||||
}
|
||||
|
||||
impl Receiver {
|
||||
pub(crate) fn load(&mut self, cx: &mut task::Context<'_>) -> Value {
|
||||
self.shared.waker.register(cx.waker());
|
||||
self.shared.value.load(Ordering::SeqCst)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn peek(&self) -> Value {
|
||||
self.shared.value.load(Ordering::Relaxed)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue