Skip to content

Commit

Permalink
Merge #180
Browse files Browse the repository at this point in the history
180: Rearrange Send/Sync impls for MbedtlsList/MbedtlsBox r=AdrianCX a=jethrogb

See rust-lang/rust#93367

Co-authored-by: Jethro Beekman <jethro@fortanix.com>
  • Loading branch information
2 people authored and Taowyoo committed Apr 24, 2023
1 parent aa500d0 commit 6726a5a
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 68 deletions.
4 changes: 3 additions & 1 deletion mbedtls/src/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,10 @@ impl<T> Drop for Box<T> {
}
}

unsafe impl<T: Send> Send for Box<T> {}
unsafe impl<T: Sync> Sync for Box<T> {}

#[repr(transparent)]
pub struct List<T> {
pub(crate) inner: Option<Box<T>>
}

66 changes: 66 additions & 0 deletions mbedtls/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,69 @@ cfg_if::cfg_if! {
pub unsafe fn set_global_debug_threshold(threshold: i32) {
mbedtls_sys::debug_set_threshold(threshold);
}

#[cfg(test)]
mod tests {
#[allow(dead_code)]
/// Utilities for testing whether types implement certain traits.
///
/// For each trait `Trait` that you want to be able to test, you should
/// implement:
/// ```ignore
/// impl<T: “Trait”> Testable<dyn “Trait”> for T {}
/// ```
///
/// Then, to test whether a type `Type` implements `Trait`, call:
/// ```ignore
/// TestTrait::<dyn “Trait”, “Type”>::new().impls_trait()
/// ```
/// This returns a `bool` indicating whether the trait is implemented.
// This relies on auto-deref to distinguish between types that do and don't
// implement the trait.
mod testtrait {
use core::marker::PhantomData;

pub struct NonImplTrait<T> {
inner: PhantomData<T>
}

pub struct TestTrait<TraitObj: ?Sized, Type> {
non_impl: NonImplTrait<Type>,
phantom: PhantomData<*const TraitObj>,
}

pub trait Testable<T: ?Sized> {}

impl<TraitObj: ?Sized, Type> TestTrait<TraitObj, Type> {
pub fn new() -> Self {
TestTrait { non_impl: NonImplTrait { inner: PhantomData }, phantom: PhantomData }
}
}

impl<TraitObj: ?Sized, Type: Testable<TraitObj>> TestTrait<TraitObj, Type> {
pub fn impls_trait(&self) -> bool {
true
}
}

impl<T> NonImplTrait<T> {
pub fn impls_trait(&self) -> bool {
false
}
}

impl<TraitObj: ?Sized, Type> core::ops::Deref for TestTrait<TraitObj, Type> {
type Target = NonImplTrait<Type>;

fn deref(&self) -> &NonImplTrait<Type> {
&self.non_impl
}
}
}

pub use testtrait::{TestTrait, Testable};

impl<T: Send> Testable<dyn Send> for T {}
impl<T: Sync> Testable<dyn Sync> for T {}
impl<T: Send + Sync> Testable<dyn Send + Sync> for T {}
}
60 changes: 1 addition & 59 deletions mbedtls/src/wrapper_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,69 +301,11 @@ macro_rules! getter {

#[cfg(test)]
mod tests {
#[allow(dead_code)]
/// Utilities for testing whether types implement certain traits.
///
/// For each trait `Trait` that you want to be able to test, you should
/// implement:
/// ```ignore
/// impl<T: “Trait”> Testable<dyn “Trait”> for T {}
/// ```
///
/// Then, to test whether a type `Type` implements `Trait`, call:
/// ```ignore
/// TestTrait::<dyn “Trait”, “Type”>::new().impls_trait()
/// ```
/// This returns a `bool` indicating whether the trait is implemented.
// This relies on auto-deref to distinguish between types that do and don't
// implement the trait.
mod testtrait {
use core::marker::PhantomData;

pub struct NonImplTrait<T> {
inner: PhantomData<T>
}

pub struct TestTrait<TraitObj: ?Sized, Type> {
non_impl: NonImplTrait<Type>,
phantom: PhantomData<*const TraitObj>,
}

pub trait Testable<T: ?Sized> {}

impl<TraitObj: ?Sized, Type> TestTrait<TraitObj, Type> {
pub fn new() -> Self {
TestTrait { non_impl: NonImplTrait { inner: PhantomData }, phantom: PhantomData }
}
}

impl<TraitObj: ?Sized, Type: Testable<TraitObj>> TestTrait<TraitObj, Type> {
pub fn impls_trait(&self) -> bool {
true
}
}

impl<T> NonImplTrait<T> {
pub fn impls_trait(&self) -> bool {
false
}
}

impl<TraitObj: ?Sized, Type> core::ops::Deref for TestTrait<TraitObj, Type> {
type Target = NonImplTrait<Type>;

fn deref(&self) -> &NonImplTrait<Type> {
&self.non_impl
}
}
}

use testtrait::{TestTrait, Testable};
use crate::tests::{TestTrait, Testable};

callback!(RustTest: Fn() -> ());
callback!(NativeTestMut,NativeTest() -> ());

impl<T: Send + Sync> Testable<dyn Send + Sync> for T {}
impl<T: RustTest> Testable<dyn RustTest> for T {}
impl<T: NativeTest> Testable<dyn NativeTest> for T {}
impl<T: NativeTestMut> Testable<dyn NativeTestMut> for T {}
Expand Down
20 changes: 12 additions & 8 deletions mbedtls/src/x509/certificate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ define!(
impl<'a> UnsafeFrom<ptr> {}
);

unsafe impl Sync for Certificate {}

fn x509_buf_to_vec(buf: &x509_buf) -> Vec<u8> {
if buf.p.is_null() || buf.len == 0 {
return vec![];
Expand Down Expand Up @@ -494,10 +496,6 @@ impl<'a> Builder<'a> {
// x509write_crt_set_subject_key_identifier
//

unsafe impl Send for MbedtlsBox<Certificate> {}

unsafe impl Sync for MbedtlsBox<Certificate> {}

impl MbedtlsBox<Certificate> {
fn init() -> Result<Self> {
unsafe {
Expand Down Expand Up @@ -556,10 +554,6 @@ impl<'a> UnsafeFrom<*mut *mut x509_crt> for &'a mut Option<MbedtlsBox<Certificat
}
}

unsafe impl Send for MbedtlsList<Certificate> {}

unsafe impl Sync for MbedtlsList<Certificate> {}

impl MbedtlsList<Certificate> {
pub fn new() -> Self {
Self { inner: None }
Expand Down Expand Up @@ -1439,4 +1433,14 @@ cYp0bH/RcPTC0Z+ZaqSWMtfxRrk63MJQF9EXpDCdvQRcTMD9D85DJrMKn8aumq0M
let cert : &mut Certificate = unsafe { UnsafeFrom::from(ptr).unwrap() };
assert_eq!(c1_info, format!("{:?}", cert));
}

#[test]
fn cert_send_sync() {
assert!(crate::tests::TestTrait::<dyn Send, Certificate>::new().impls_trait(), "Certificate should be Send");
assert!(crate::tests::TestTrait::<dyn Send, MbedtlsBox<Certificate>>::new().impls_trait(), "MbedtlsBox<Certificate> should be Send");
assert!(crate::tests::TestTrait::<dyn Send, MbedtlsList<Certificate>>::new().impls_trait(), "MbedtlsList<Certificate> should be Send");
assert!(crate::tests::TestTrait::<dyn Sync, Certificate>::new().impls_trait(), "Certificate should be Sync");
assert!(crate::tests::TestTrait::<dyn Sync, MbedtlsBox<Certificate>>::new().impls_trait(), "MbedtlsBox<Certificate> should be Sync");
assert!(crate::tests::TestTrait::<dyn Sync, MbedtlsList<Certificate>>::new().impls_trait(), "MbedtlsList<Certificate> should be Sync");
}
}

0 comments on commit 6726a5a

Please sign in to comment.