aboutsummaryrefslogtreecommitdiff
path: root/openssl/src/ssl/bio.rs
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2015-12-18 21:19:16 -0800
committerSteven Fackler <[email protected]>2015-12-18 21:20:47 -0800
commite85b49d3755375b3e535cbd4b07d4fbf953948cb (patch)
treea084b204972855d4dc2b66cec999ebd93c7a3078 /openssl/src/ssl/bio.rs
parentMerge pull request #324 from gentoo90/deps (diff)
downloadrust-openssl-e85b49d3755375b3e535cbd4b07d4fbf953948cb.tar.xz
rust-openssl-e85b49d3755375b3e535cbd4b07d4fbf953948cb.zip
Work around the worst of clone bogusness
SslStream::{clone,try_clone} are inherently broken since the Ssl object shared by both streams is only going to be talking to one stream. Stuff like hyper depends on try_clone, so we'll leave it here for now but minimize the brokenness to "no worse than what it used to be like". They'll be removed in 0.8. cc #325
Diffstat (limited to 'openssl/src/ssl/bio.rs')
-rw-r--r--openssl/src/ssl/bio.rs38
1 files changed, 9 insertions, 29 deletions
diff --git a/openssl/src/ssl/bio.rs b/openssl/src/ssl/bio.rs
index ef63d146..99d9af0a 100644
--- a/openssl/src/ssl/bio.rs
+++ b/openssl/src/ssl/bio.rs
@@ -6,35 +6,20 @@ use std::io::prelude::*;
use std::mem;
use std::slice;
use std::ptr;
+use std::sync::Arc;
use ssl::error::SslError;
// "rust"
const NAME: [c_char; 5] = [114, 117, 115, 116, 0];
-// we use this after removing the stream from the BIO so that we don't have to
-// worry about freeing the heap allocated BIO_METHOD after freeing the BIO.
-static DESTROY_METHOD: BIO_METHOD = BIO_METHOD {
- type_: BIO_TYPE_NONE,
- name: &NAME[0],
- bwrite: None,
- bread: None,
- bputs: None,
- bgets: None,
- ctrl: None,
- create: None,
- destroy: Some(destroy),
- callback_ctrl: None,
-};
-
pub struct StreamState<S> {
pub stream: S,
pub error: Option<io::Error>,
}
-pub fn new<S: Read + Write>(stream: S) -> Result<(*mut BIO, Box<BIO_METHOD>), SslError> {
-
- let method = Box::new(BIO_METHOD {
+pub fn new<S: Read + Write>(stream: S) -> Result<(*mut BIO, Arc<BIO_METHOD>), SslError> {
+ let method = Arc::new(BIO_METHOD {
type_: BIO_TYPE_NONE,
name: &NAME[0],
bwrite: Some(bwrite::<S>),
@@ -43,7 +28,7 @@ pub fn new<S: Read + Write>(stream: S) -> Result<(*mut BIO, Box<BIO_METHOD>), Ss
bgets: None,
ctrl: Some(ctrl::<S>),
create: Some(create),
- destroy: None, // covered in the replacement BIO_METHOD
+ destroy: Some(destroy::<S>),
callback_ctrl: None,
});
@@ -66,14 +51,6 @@ pub unsafe fn take_error<S>(bio: *mut BIO) -> Option<io::Error> {
state.error.take()
}
-pub unsafe fn take_stream<S>(bio: *mut BIO) -> S {
- let state: Box<StreamState<S>> = Box::from_raw((*bio).ptr as *mut _);
- (*bio).ptr = ptr::null_mut();
- (*bio).method = &DESTROY_METHOD as *const _ as *mut _;
- (*bio).init = 0;
- state.stream
-}
-
pub unsafe fn get_ref<'a, S: 'a>(bio: *mut BIO) -> &'a S {
let state: &'a StreamState<S> = mem::transmute((*bio).ptr);
&state.stream
@@ -159,11 +136,14 @@ unsafe extern "C" fn create(bio: *mut BIO) -> c_int {
1
}
-unsafe extern "C" fn destroy(bio: *mut BIO) -> c_int {
+unsafe extern "C" fn destroy<S>(bio: *mut BIO) -> c_int {
if bio.is_null() {
return 0;
}
- assert!((*bio).ptr.is_null());
+ assert!(!(*bio).ptr.is_null());
+ Box::<StreamState<S>>::from_raw((*bio).ptr as *mut _);
+ (*bio).ptr = ptr::null_mut();
+ (*bio).init = 0;
1
}