initialize recycled data
This commit is contained in:
@ -63,6 +63,19 @@ impl Default for Packet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait Recycle {
|
||||||
|
// Recycle trait is an object that can re-initialize important parts
|
||||||
|
// of itself, similar to Default, but not necessarily a full clear
|
||||||
|
// also, we do it in-place.
|
||||||
|
fn reset(&mut self) -> ();
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Recycle for Packet {
|
||||||
|
fn reset(&mut self) -> () {
|
||||||
|
self.meta = Meta::default();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Meta {
|
impl Meta {
|
||||||
pub fn addr(&self) -> SocketAddr {
|
pub fn addr(&self) -> SocketAddr {
|
||||||
if !self.v6 {
|
if !self.v6 {
|
||||||
@ -113,6 +126,14 @@ impl Default for Packets {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Recycle for Packets {
|
||||||
|
fn reset(&mut self) -> () {
|
||||||
|
for i in 0..self.packets.len() {
|
||||||
|
self.packets[i].reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Blob {
|
pub struct Blob {
|
||||||
pub data: [u8; BLOB_SIZE],
|
pub data: [u8; BLOB_SIZE],
|
||||||
@ -140,6 +161,13 @@ impl Default for Blob {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Recycle for Blob {
|
||||||
|
fn reset(&mut self) -> () {
|
||||||
|
self.meta = Meta::default();
|
||||||
|
self.data[..BLOB_HEADER_SIZE].copy_from_slice(&[0u8; BLOB_HEADER_SIZE]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum BlobError {
|
pub enum BlobError {
|
||||||
/// the Blob's meta and data are not self-consistent
|
/// the Blob's meta and data are not self-consistent
|
||||||
@ -166,25 +194,35 @@ impl<T: Default> Clone for Recycler<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Default> Recycler<T> {
|
impl<T: Default + Recycle> Recycler<T> {
|
||||||
pub fn allocate(&self) -> Arc<RwLock<T>> {
|
pub fn allocate(&self) -> Arc<RwLock<T>> {
|
||||||
let mut gc = self.gc.lock().expect("recycler lock in pb fn allocate");
|
let mut gc = self.gc.lock().expect("recycler lock in pb fn allocate");
|
||||||
let x = gc
|
|
||||||
.pop()
|
|
||||||
.unwrap_or_else(|| Arc::new(RwLock::new(Default::default())));
|
|
||||||
|
|
||||||
// Only return the item if this recycler is the last reference to it.
|
loop {
|
||||||
// Remove this check once `T` holds a Weak reference back to this
|
if let Some(x) = gc.pop() {
|
||||||
// recycler and implements `Drop`. At the time of this writing, Weak can't
|
// Only return the item if this recycler is the last reference to it.
|
||||||
// be passed across threads ('alloc' is a nightly-only API), and so our
|
// Remove this check once `T` holds a Weak reference back to this
|
||||||
// reference-counted recyclables are awkwardly being recycled by hand,
|
// recycler and implements `Drop`. At the time of this writing, Weak can't
|
||||||
// which allows this race condition to exist.
|
// be passed across threads ('alloc' is a nightly-only API), and so our
|
||||||
if Arc::strong_count(&x) > 1 {
|
// reference-counted recyclables are awkwardly being recycled by hand,
|
||||||
warn!("Recycled item still in use. Booting it.");
|
// which allows this race condition to exist.
|
||||||
drop(gc);
|
if Arc::strong_count(&x) >= 1 {
|
||||||
self.allocate()
|
// Commenting out this message, is annoying for known use case of
|
||||||
} else {
|
// validator hanging onto a blob in the window, but also sending it over
|
||||||
x
|
// to retransmmit_request
|
||||||
|
//
|
||||||
|
// warn!("Recycled item still in use. Booting it.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut w = x.write().unwrap();
|
||||||
|
w.reset();
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
} else {
|
||||||
|
return Arc::new(RwLock::new(Default::default()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn recycle(&self, x: Arc<RwLock<T>>) {
|
pub fn recycle(&self, x: Arc<RwLock<T>>) {
|
||||||
|
Reference in New Issue
Block a user