From 2b84e6726378292139500988cf051a4d71eaf5c2 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Fri, 15 Jan 2021 12:18:03 +0100 Subject: [PATCH] Make Opaque a newtype And add Sync to its bounds Fixes: #2641 --- src/api/test.rs | 2 +- src/api/util.rs | 22 +++++++++++++++++++++- src/capi.rs | 3 ++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/api/test.rs b/src/api/test.rs index 21d8fa3459..5cbeaa6ea1 100644 --- a/src/api/test.rs +++ b/src/api/test.rs @@ -1176,7 +1176,7 @@ fn send_frame_kf(ctx: &mut Context, keyframe: bool) { let frame_type_override = if keyframe { FrameTypeOverride::Key } else { FrameTypeOverride::No }; - let opaque = Some(Box::new(keyframe) as Box); + let opaque = Some(Opaque::new(keyframe)); let fp = FrameParameters { frame_type_override, opaque }; diff --git a/src/api/util.rs b/src/api/util.rs index 4ae0056a68..71b8611a9e 100644 --- a/src/api/util.rs +++ b/src/api/util.rs @@ -20,7 +20,27 @@ use std::sync::Arc; use thiserror::*; /// Opaque type to be passed from Frame to Packet -pub type Opaque = Box; +#[derive(Debug)] +pub struct Opaque(Box); + +impl Opaque { + /// Wrap a type in the opaque struct + pub fn new(t: T) -> Self { + Opaque(Box::new(t) as Box) + } + + /// Attempt to downcast the opaque to a concrete type. + pub fn downcast(self) -> Result, Opaque> { + if self.0.is::() { + unsafe { + let raw: *mut (dyn Any + Send + Sync) = Box::into_raw(self.0); + Ok(Box::from_raw(raw as *mut T)) + } + } else { + Err(self) + } + } +} // TODO: use the num crate? /// A rational number. diff --git a/src/capi.rs b/src/capi.rs index fb2ed3c4f7..d0aeda1f82 100644 --- a/src/capi.rs +++ b/src/capi.rs @@ -67,6 +67,7 @@ struct FrameOpaque { } unsafe impl Send for FrameOpaque {} +unsafe impl Sync for FrameOpaque {} impl Default for FrameOpaque { fn default() -> Self { @@ -1062,7 +1063,7 @@ pub unsafe extern fn rav1e_send_frame( let maybe_opaque = if frame.is_null() { None } else { - (*frame).opaque.take().map(|o| Box::new(o) as rav1e::Opaque) + (*frame).opaque.take().map(|o| rav1e::Opaque::new(o)) }; let ret = (*ctx)