Skip to content

Rearrange Send/Sync impls for MbedtlsList/MbedtlsBox #180

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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");
}
}