Fix Send + Sync-ness of SslStream
This commit is contained in:
parent
cb44256876
commit
ca71e00878
|
|
@ -7,7 +7,6 @@ use std::io::prelude::*;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use cvt_p;
|
use cvt_p;
|
||||||
use error::ErrorStack;
|
use error::ErrorStack;
|
||||||
|
|
@ -22,15 +21,16 @@ pub struct StreamState<S> {
|
||||||
pub struct BioMethod(compat::BIO_METHOD);
|
pub struct BioMethod(compat::BIO_METHOD);
|
||||||
|
|
||||||
impl BioMethod {
|
impl BioMethod {
|
||||||
pub fn new<S: Read + Write>() -> BioMethod {
|
fn new<S: Read + Write>() -> BioMethod {
|
||||||
BioMethod(compat::BIO_METHOD::new::<S>())
|
BioMethod(compat::BIO_METHOD::new::<S>())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl Sync for BioMethod {}
|
||||||
unsafe impl Send for BioMethod {}
|
unsafe impl Send for BioMethod {}
|
||||||
|
|
||||||
pub fn new<S: Read + Write>(stream: S) -> Result<(*mut BIO, Arc<BioMethod>), ErrorStack> {
|
pub fn new<S: Read + Write>(stream: S) -> Result<(*mut BIO, BioMethod), ErrorStack> {
|
||||||
let method = Arc::new(BioMethod::new::<S>());
|
let method = BioMethod::new::<S>();
|
||||||
|
|
||||||
let state = Box::new(StreamState {
|
let state = Box::new(StreamState {
|
||||||
stream: stream,
|
stream: stream,
|
||||||
|
|
@ -188,9 +188,7 @@ mod compat {
|
||||||
|
|
||||||
pub unsafe fn BIO_set_num(_bio: *mut ffi::BIO, _num: c_int) {}
|
pub unsafe fn BIO_set_num(_bio: *mut ffi::BIO, _num: c_int) {}
|
||||||
|
|
||||||
pub struct BIO_METHOD {
|
pub struct BIO_METHOD(*mut ffi::BIO_METHOD);
|
||||||
inner: *mut ffi::BIO_METHOD,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BIO_METHOD {
|
impl BIO_METHOD {
|
||||||
pub fn new<S: Read + Write>() -> BIO_METHOD {
|
pub fn new<S: Read + Write>() -> BIO_METHOD {
|
||||||
|
|
@ -198,7 +196,7 @@ mod compat {
|
||||||
let ptr = ffi::BIO_meth_new(ffi::BIO_TYPE_NONE,
|
let ptr = ffi::BIO_meth_new(ffi::BIO_TYPE_NONE,
|
||||||
b"rust\0".as_ptr() as *const _);
|
b"rust\0".as_ptr() as *const _);
|
||||||
assert!(!ptr.is_null());
|
assert!(!ptr.is_null());
|
||||||
let ret = BIO_METHOD { inner: ptr };
|
let ret = BIO_METHOD(ptr);
|
||||||
assert!(ffi::BIO_meth_set_write(ptr, super::bwrite::<S>) != 0);
|
assert!(ffi::BIO_meth_set_write(ptr, super::bwrite::<S>) != 0);
|
||||||
assert!(ffi::BIO_meth_set_read(ptr, super::bread::<S>) != 0);
|
assert!(ffi::BIO_meth_set_read(ptr, super::bread::<S>) != 0);
|
||||||
assert!(ffi::BIO_meth_set_puts(ptr, super::bputs::<S>) != 0);
|
assert!(ffi::BIO_meth_set_puts(ptr, super::bputs::<S>) != 0);
|
||||||
|
|
@ -210,14 +208,14 @@ mod compat {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self) -> *mut ffi::BIO_METHOD {
|
pub fn get(&self) -> *mut ffi::BIO_METHOD {
|
||||||
self.inner
|
self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for BIO_METHOD {
|
impl Drop for BIO_METHOD {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
ffi::BIO_meth_free(self.inner);
|
ffi::BIO_meth_free(self.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -227,19 +225,15 @@ mod compat {
|
||||||
#[allow(bad_style)]
|
#[allow(bad_style)]
|
||||||
mod compat {
|
mod compat {
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::cell::UnsafeCell;
|
|
||||||
|
|
||||||
use ffi;
|
use ffi;
|
||||||
use libc::{c_int, c_void};
|
use libc::{c_int, c_void};
|
||||||
|
|
||||||
pub struct BIO_METHOD {
|
pub struct BIO_METHOD(*mut ffi::BIO_METHOD);
|
||||||
inner: UnsafeCell<ffi::BIO_METHOD>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BIO_METHOD {
|
impl BIO_METHOD {
|
||||||
pub fn new<S: Read + Write>() -> BIO_METHOD {
|
pub fn new<S: Read + Write>() -> BIO_METHOD {
|
||||||
BIO_METHOD {
|
let ptr = Box::new(ffi::BIO_METHOD {
|
||||||
inner: UnsafeCell::new(ffi::BIO_METHOD {
|
|
||||||
type_: ffi::BIO_TYPE_NONE,
|
type_: ffi::BIO_TYPE_NONE,
|
||||||
name: b"rust\0".as_ptr() as *const _,
|
name: b"rust\0".as_ptr() as *const _,
|
||||||
bwrite: Some(super::bwrite::<S>),
|
bwrite: Some(super::bwrite::<S>),
|
||||||
|
|
@ -250,12 +244,21 @@ mod compat {
|
||||||
create: Some(super::create),
|
create: Some(super::create),
|
||||||
destroy: Some(super::destroy::<S>),
|
destroy: Some(super::destroy::<S>),
|
||||||
callback_ctrl: None,
|
callback_ctrl: None,
|
||||||
}),
|
});
|
||||||
}
|
|
||||||
|
BIO_METHOD(Box::into_raw(ptr))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self) -> *mut ffi::BIO_METHOD {
|
pub fn get(&self) -> *mut ffi::BIO_METHOD {
|
||||||
self.inner.get()
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for BIO_METHOD {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
Box::<ffi::BIO_METHOD>::from_raw(self.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use std::ops::{Deref, DerefMut};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::sync::{Mutex, Arc};
|
use std::sync::Mutex;
|
||||||
use libc::{c_uchar, c_uint};
|
use libc::{c_uchar, c_uint};
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
@ -1023,6 +1023,9 @@ impl SslRef {
|
||||||
|
|
||||||
pub struct Ssl(*mut ffi::SSL);
|
pub struct Ssl(*mut ffi::SSL);
|
||||||
|
|
||||||
|
unsafe impl Sync for Ssl {}
|
||||||
|
unsafe impl Send for Ssl {}
|
||||||
|
|
||||||
impl fmt::Debug for Ssl {
|
impl fmt::Debug for Ssl {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let mut builder = fmt.debug_struct("Ssl");
|
let mut builder = fmt.debug_struct("Ssl");
|
||||||
|
|
@ -1128,12 +1131,10 @@ impl Ssl {
|
||||||
/// A stream wrapper which handles SSL encryption for an underlying stream.
|
/// A stream wrapper which handles SSL encryption for an underlying stream.
|
||||||
pub struct SslStream<S> {
|
pub struct SslStream<S> {
|
||||||
ssl: Ssl,
|
ssl: Ssl,
|
||||||
_method: Arc<BioMethod>, // NOTE: this *must* be after the Ssl field so things drop right
|
_method: BioMethod, // NOTE: this *must* be after the Ssl field so things drop right
|
||||||
_p: PhantomData<S>,
|
_p: PhantomData<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<S: Send> Send for SslStream<S> {}
|
|
||||||
|
|
||||||
impl<S> fmt::Debug for SslStream<S>
|
impl<S> fmt::Debug for SslStream<S>
|
||||||
where S: fmt::Debug
|
where S: fmt::Debug
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1083,3 +1083,11 @@ fn invalid_hostname() {
|
||||||
let s = TcpStream::connect("google.com:443").unwrap();
|
let s = TcpStream::connect("google.com:443").unwrap();
|
||||||
assert!(ssl.connect(s).is_err());
|
assert!(ssl.connect(s).is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn _check_kinds() {
|
||||||
|
fn is_send<T: Send>() {}
|
||||||
|
fn is_sync<T: Sync>() {}
|
||||||
|
|
||||||
|
is_send::<SslStream<TcpStream>>();
|
||||||
|
is_sync::<SslStream<TcpStream>>();
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue