From a9c8dae84be991fa2aef9eb9a90b01d1a49d9733 Mon Sep 17 00:00:00 2001 From: asonix Date: Sun, 28 Jan 2024 12:55:48 -0600 Subject: [PATCH] Erase SHARDS const generic from Sender --- src/lib.rs | 58 +++++++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 6589ed4..396b368 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,38 +16,46 @@ use rustls::sign::CertifiedKey; /// contention, leading to faster reads but more writes per call to `update`. pub fn channel( initial: CertifiedKey, -) -> (ChannelSender, Arc>) { +) -> (ChannelSender, Arc>) { let resolver = Arc::new(ChannelResolver::::new(initial)); - ( - ChannelSender { - inner: Arc::clone(&resolver), - }, - resolver, - ) + let cloned_resolver = Arc::clone(&resolver); + let inner = cloned_resolver as Arc; + + (ChannelSender { inner }, resolver) } /// The Send half of the channel. This is used for updating the server with new keys #[derive(Clone)] -pub struct ChannelSender { - inner: Arc>, +pub struct ChannelSender { + inner: Arc, +} + +mod sealed { + use std::sync::{atomic::AtomicU64, Arc, RwLock}; + + use rustls::sign::CertifiedKey; + + pub struct ChannelResolverInner { + pub(super) locks: L, + } + + pub struct Shard { + pub(super) generation: AtomicU64, + pub(super) lock: RwLock>, + } } // The Receive half of the channel. This is registerd with rustls to provide the server with keys -pub struct ChannelResolver { - locks: [Shard; SHARDS], -} - -struct Shard { - generation: AtomicU64, - lock: RwLock>, -} +pub type ChannelResolver = + sealed::ChannelResolverInner<[sealed::Shard; SHARDS]>; +type ErasedChannelResolver = sealed::ChannelResolverInner<[sealed::Shard]>; thread_local! { static LOCAL_KEY: OnceCell)>> = OnceCell::new(); } -impl Shard { +impl sealed::Shard { fn new(key: CertifiedKey) -> Self { Self { generation: AtomicU64::new(0), @@ -96,23 +104,19 @@ impl Shard { } } -impl ChannelSender { +impl ChannelSender { /// Update the key in the channel pub fn update(&self, key: CertifiedKey) { - self.inner.update(key); + for lock in &self.inner.locks { + lock.update(key.clone()); + } } } impl ChannelResolver { fn new(key: CertifiedKey) -> Self { Self { - locks: [(); SHARDS].map(|()| Shard::new(key.clone())), - } - } - - fn update(&self, key: CertifiedKey) { - for lock in &self.locks { - lock.update(key.clone()); + locks: [(); SHARDS].map(|()| sealed::Shard::new(key.clone())), } }