Created
September 3, 2020 09:28
-
-
Save rklaehn/84eaad6af3171a653ccc5f1abc03845c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// This abomination only works if the underlying bytes are known in number (Sized), | |
/// can be moved around in memory (Unpin) and do no hold on to other things than the | |
/// underlying bytes ('static). | |
#[cfg(feature = "dataflow")] | |
impl<T: Abomonation + 'static + Sized + Unpin> Abomonation for ArcVal<T> { | |
unsafe fn entomb<W: std::io::Write>(&self, write: &mut W) -> std::io::Result<()> { | |
/* Since the value T has not yet been seen by abomonate (it is behind a pointer) | |
* we need to fully encode it. | |
*/ | |
abomonation::encode(self.deref(), write) | |
} | |
unsafe fn exhume<'a, 'b>(&'a mut self, bytes: &'b mut [u8]) -> Option<&'b mut [u8]> { | |
use std::{mem, ptr}; | |
/* The idea here is to construct a new Arc<T> from the entombed bytes. | |
* The state of this ArcVal upon entry of this function contains only an invalid | |
* pointer to an ArcInner that we need to dispose of without trying to run | |
* its destructor (which would panic). | |
*/ | |
let (value, bytes) = abomonation::decode::<T>(bytes)?; | |
// value is just a reference to the first part of old bytes, so move it into a new Arc | |
let arc = Arc::new(ptr::read(value)); | |
// now swap the fresh arc into its place ... | |
let garbage = mem::replace(&mut self.0, arc); | |
// ... and forget about the old one | |
mem::forget(garbage); | |
Some(bytes) | |
} | |
fn extent(&self) -> usize { | |
std::mem::size_of::<T>() + self.deref().extent() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment