Avoid negative impls in the bridge

This commit is contained in:
bjorn3 2022-03-25 16:17:32 +01:00
parent 4b67506baa
commit ec7efa75f9
3 changed files with 32 additions and 20 deletions

View file

@ -2,6 +2,8 @@
use super::*;
use std::marker::PhantomData;
macro_rules! define_handles {
(
'owned: $($oty:ident,)*
@ -45,20 +47,25 @@ macro_rules! define_handles {
$(
#[repr(C)]
pub(crate) struct $oty(handle::Handle);
impl !Send for $oty {}
impl !Sync for $oty {}
pub(crate) struct $oty {
handle: handle::Handle,
// Prevent Send and Sync impls
_marker: PhantomData<*mut ()>,
}
// Forward `Drop::drop` to the inherent `drop` method.
impl Drop for $oty {
fn drop(&mut self) {
$oty(self.0).drop();
$oty {
handle: self.handle,
_marker: PhantomData,
}.drop();
}
}
impl<S> Encode<S> for $oty {
fn encode(self, w: &mut Writer, s: &mut S) {
let handle = self.0;
let handle = self.handle;
mem::forget(self);
handle.encode(w, s);
}
@ -74,7 +81,7 @@ macro_rules! define_handles {
impl<S> Encode<S> for &$oty {
fn encode(self, w: &mut Writer, s: &mut S) {
self.0.encode(w, s);
self.handle.encode(w, s);
}
}
@ -88,7 +95,7 @@ macro_rules! define_handles {
impl<S> Encode<S> for &mut $oty {
fn encode(self, w: &mut Writer, s: &mut S) {
self.0.encode(w, s);
self.handle.encode(w, s);
}
}
@ -113,7 +120,10 @@ macro_rules! define_handles {
impl<S> DecodeMut<'_, '_, S> for $oty {
fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
$oty(handle::Handle::decode(r, s))
$oty {
handle: handle::Handle::decode(r, s),
_marker: PhantomData,
}
}
}
)*
@ -121,13 +131,15 @@ macro_rules! define_handles {
$(
#[repr(C)]
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub(crate) struct $ity(handle::Handle);
impl !Send for $ity {}
impl !Sync for $ity {}
pub(crate) struct $ity {
handle: handle::Handle,
// Prevent Send and Sync impls
_marker: PhantomData<*mut ()>,
}
impl<S> Encode<S> for $ity {
fn encode(self, w: &mut Writer, s: &mut S) {
self.0.encode(w, s);
self.handle.encode(w, s);
}
}
@ -149,7 +161,10 @@ macro_rules! define_handles {
impl<S> DecodeMut<'_, '_, S> for $ity {
fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
$ity(handle::Handle::decode(r, s))
$ity {
handle: handle::Handle::decode(r, s),
_marker: PhantomData,
}
}
}
)*

View file

@ -6,14 +6,12 @@ use std::marker::PhantomData;
pub struct Closure<'a, A, R> {
call: unsafe extern "C" fn(*mut Env, A) -> R,
env: *mut Env,
_marker: PhantomData<&'a mut ()>,
// Ensure Closure is !Send and !Sync
_marker: PhantomData<*mut &'a mut ()>,
}
struct Env;
impl<'a, A, R> !Sync for Closure<'a, A, R> {}
impl<'a, A, R> !Send for Closure<'a, A, R> {}
impl<'a, A, R, F: FnMut(A) -> R> From<&'a mut F> for Closure<'a, A, R> {
fn from(f: &'a mut F) -> Self {
unsafe extern "C" fn call<A, R, F: FnMut(A) -> R>(env: *mut Env, arg: A) -> R {

View file

@ -220,6 +220,8 @@ use rpc::{Decode, DecodeMut, Encode, Reader, Writer};
/// then passes it to the client through the function pointer in the `run`
/// field of `client::Client`. The client holds its copy of the `Bridge`
/// in TLS during its execution (`Bridge::{enter, with}` in `client.rs`).
// Note: Bridge is !Send and !Sync due to containg a `Closure`. If this
// ever changes, make sure to preserve the !Send and !Sync property.
#[repr(C)]
pub struct Bridge<'a> {
/// Reusable buffer (only `clear`-ed, never shrunk), primarily
@ -233,9 +235,6 @@ pub struct Bridge<'a> {
force_show_panics: bool,
}
impl<'a> !Sync for Bridge<'a> {}
impl<'a> !Send for Bridge<'a> {}
#[forbid(unsafe_code)]
#[allow(non_camel_case_types)]
mod api_tags {