diff --git a/src/ffi/mod.rs b/src/ffi/mod.rs index 47316fcaca260e0ae036d42f61d3bb528b1d4a02..5da3932760a828cd85ded7b00e1b226c124bfadc 100644 --- a/src/ffi/mod.rs +++ b/src/ffi/mod.rs @@ -1,11 +1,11 @@ use crate::{common::*, runtime::*}; use core::{cell::RefCell, convert::TryFrom}; +use std::os::raw::c_int; use std::slice::from_raw_parts as slice_from_raw_parts; #[cfg(feature = "ffi_socket_api")] pub mod socket_api; /////////////////////////////////////////////// -type ErrorCode = std::os::raw::c_int; #[derive(Default)] struct StoredError { // invariant: len is zero IFF its occupied @@ -65,19 +65,26 @@ thread_local! { unsafe fn tl_socketaddr_from_raw( bytes_ptr: *const u8, bytes_len: usize, -) -> Result { +) -> Result { std::str::from_utf8(&*slice_from_raw_parts(bytes_ptr, bytes_len)) .map_err(|err| { StoredError::tl_debug_store(&err); - -1 + ERR_REOWOLF })? .parse() .map_err(|err| { StoredError::tl_debug_store(&err); - -2 + ERR_REOWOLF }) } +pub const ERR_OK: c_int = 0; +pub const ERR_REOWOLF: c_int = -1; +pub const WRONG_STATE: c_int = -2; +pub const FD_LOCK_POISONED: c_int = -3; +pub const CLOSE_FAIL: c_int = -4; +pub const BAD_FD: c_int = -5; + ///////////////////// REOWOLF ////////////////////////// /// Returns length (via out pointer) and pointer (via return value) of the last Reowolf error. @@ -208,16 +215,16 @@ pub unsafe extern "C" fn connector_add_component( ident_len: usize, ports_ptr: *const PortId, ports_len: usize, -) -> ErrorCode { +) -> c_int { StoredError::tl_clear(); match connector.add_component( &*slice_from_raw_parts(ident_ptr, ident_len), &*slice_from_raw_parts(ports_ptr, ports_len), ) { - Ok(()) => 0, + Ok(()) => ERR_OK, Err(err) => { StoredError::tl_debug_store(&err); - -1 + ERR_REOWOLF } } } @@ -236,7 +243,7 @@ pub unsafe extern "C" fn connector_add_net_port( addr_str_len: usize, port_polarity: Polarity, endpoint_polarity: EndpointPolarity, -) -> ErrorCode { +) -> c_int { StoredError::tl_clear(); let addr = match tl_socketaddr_from_raw(addr_str_ptr, addr_str_len) { Ok(local) => local, @@ -247,11 +254,11 @@ pub unsafe extern "C" fn connector_add_net_port( if !port.is_null() { port.write(p); } - 0 + ERR_OK } Err(err) => { StoredError::tl_debug_store(&err); - -3 + ERR_REOWOLF } } } @@ -272,7 +279,7 @@ pub unsafe extern "C" fn connector_add_udp_port( local_addr_str_len: usize, peer_addr_str_ptr: *const u8, peer_addr_str_len: usize, -) -> ErrorCode { +) -> c_int { StoredError::tl_clear(); let local = match tl_socketaddr_from_raw(local_addr_str_ptr, local_addr_str_len) { Ok(local) => local, @@ -290,11 +297,11 @@ pub unsafe extern "C" fn connector_add_udp_port( if !getter.is_null() { getter.write(g); } - 0 + ERR_OK } Err(err) => { StoredError::tl_debug_store(&err); - -3 + ERR_REOWOLF } } } @@ -305,15 +312,15 @@ pub unsafe extern "C" fn connector_add_udp_port( pub unsafe extern "C" fn connector_connect( connector: &mut Connector, timeout_millis: i64, -) -> ErrorCode { +) -> c_int { StoredError::tl_clear(); let option_timeout_millis: Option = TryFrom::try_from(timeout_millis).ok(); let timeout = option_timeout_millis.map(Duration::from_millis); match connector.connect(timeout) { - Ok(()) => 0, + Ok(()) => ERR_OK, Err(err) => { StoredError::tl_debug_store(&err); - -1 + ERR_REOWOLF } } } @@ -323,7 +330,7 @@ pub unsafe extern "C" fn connector_connect( // connector: &mut Connector, // port: PortId, // payload: *mut Payload, -// ) -> ErrorCode { +// ) -> c_int { // match connector.put(port, payload.read()) { // Ok(()) => 0, // Err(err) => { @@ -338,7 +345,7 @@ pub unsafe extern "C" fn connector_connect( // connector: &mut Connector, // port: PortId, // payload: &Payload, -// ) -> ErrorCode { +// ) -> c_int { // match connector.put(port, payload.clone()) { // Ok(()) => 0, // Err(err) => { @@ -356,25 +363,25 @@ pub unsafe extern "C" fn connector_put_bytes( port: PortId, bytes_ptr: *const u8, bytes_len: usize, -) -> ErrorCode { +) -> c_int { StoredError::tl_clear(); let bytes = &*slice_from_raw_parts(bytes_ptr, bytes_len); match connector.put(port, Payload::from(bytes)) { - Ok(()) => 0, + Ok(()) => ERR_OK, Err(err) => { StoredError::tl_debug_store(&err); - -1 + ERR_REOWOLF } } } #[no_mangle] -pub unsafe extern "C" fn connector_get(connector: &mut Connector, port: PortId) -> ErrorCode { +pub unsafe extern "C" fn connector_get(connector: &mut Connector, port: PortId) -> c_int { match connector.get(port) { - Ok(()) => 0, + Ok(()) => ERR_OK, Err(err) => { StoredError::tl_debug_store(&err); - -1 + ERR_REOWOLF } } } @@ -385,7 +392,7 @@ pub unsafe extern "C" fn connector_next_batch(connector: &mut Connector) -> isiz Ok(n) => n as isize, Err(err) => { StoredError::tl_debug_store(&err); - -1 + ERR_REOWOLF as isize } } } @@ -399,7 +406,7 @@ pub unsafe extern "C" fn connector_sync(connector: &mut Connector, timeout_milli Ok(n) => n as isize, Err(err) => { StoredError::tl_debug_store(&err); - -1 + ERR_REOWOLF as isize } } } diff --git a/src/ffi/socket_api.rs b/src/ffi/socket_api.rs index e18b04647214a3936ed15d5bb8a18bd34af91bf5..92a688c54ab2e3e7f64df79f8e36c5d16007745c 100644 --- a/src/ffi/socket_api.rs +++ b/src/ffi/socket_api.rs @@ -1,3 +1,4 @@ +use super::*; use atomic_refcell::AtomicRefCell; use std::{collections::HashMap, ffi::c_void, net::SocketAddr, os::raw::c_int, sync::RwLock}; /////////////////////////////////////////////////////////////////// @@ -50,7 +51,7 @@ lazy_static::lazy_static! { #[no_mangle] pub extern "C" fn socket(_domain: c_int, _type: c_int) -> c_int { // assuming _domain is AF_INET and _type is SOCK_DGRAM - let mut w = CONNECTOR_STORAGE.write().expect("Fd lock poisoned!"); + let w = if let Some(w) = CONNECTOR_STORAGE.write() { w } else { return FD_LOCK_POISONED }; let fd = w.fd_allocator.alloc(); w.fd_to_connector.insert(fd, AtomicRefCell::new(MaybeConnector::New)); fd @@ -59,12 +60,12 @@ pub extern "C" fn socket(_domain: c_int, _type: c_int) -> c_int { #[no_mangle] pub extern "C" fn close(fd: ConnectorFd, _how: c_int) -> c_int { // ignoring HOW - let mut w = CONNECTOR_STORAGE.write().expect("Fd lock poisoned!"); + let w = if let Some(w) = CONNECTOR_STORAGE.write() { w } else { return FD_LOCK_POISONED }; w.fd_allocator.free(fd); if w.fd_to_connector.remove(&fd).is_some() { - 0 + ERR_OK } else { - -1 + CLOSE_FAIL } } @@ -72,20 +73,12 @@ pub extern "C" fn close(fd: ConnectorFd, _how: c_int) -> c_int { pub extern "C" fn bind(fd: ConnectorFd, address: *const SocketAddr, _address_len: usize) -> c_int { use MaybeConnector as Mc; // assuming _domain is AF_INET and _type is SOCK_DGRAM - let r = CONNECTOR_STORAGE.read().expect("Fd lock poisoned!"); - if let Some(maybe_conn) = r.fd_to_connector.get(&fd) { - let mc: &mut Mc = &mut maybe_conn.borrow_mut(); - match mc { - Mc::New => { - *mc = Mc::Bound(address.read()); - 0 - } - _ => -1, // connector in wrong state - } - } else { - // no connector for this fd - return -2; - } + let r = if let Some(r) = CONNECTOR_STORAGE.read() { r } else { return FD_LOCK_POISONED }; + let mc = if let Some(mc) = r.fd_to_connector.get(&fd) { mc } else { return BAD_FD }; + let mc: &mut Mc = &mut maybe_conn.borrow_mut(); + let _ = if let Mc::New = mc { () } else { return WRONG_STATE }; + *mc = Mc::Bound(address.read()); + ERR_OK } #[no_mangle] @@ -96,37 +89,21 @@ pub extern "C" fn connect( ) -> c_int { use MaybeConnector as Mc; // assuming _domain is AF_INET and _type is SOCK_DGRAM - let r = CONNECTOR_STORAGE.read().expect("Fd lock poisoned!"); - if let Some(maybe_conn) = r.fd_to_connector.get(&fd) { - let mc: &mut Mc = &mut maybe_conn.borrow_mut(); - match mc { - Mc::Bound(_local) => { - *mc = Mc::Connected(Connector {}); - 0 - } - _ => -1, // connector in wrong state - } - } else { - // no connector for this fd - return -2; - } + let r = if let Some(r) = CONNECTOR_STORAGE.read() { r } else { return FD_LOCK_POISONED }; + let mc = if let Some(mc) = r.fd_to_connector.get(&fd) { mc } else { return BAD_FD }; + let mc: &mut Mc = &mut maybe_conn.borrow_mut(); + let local = if let Mc::Bound(local) = mc { local } else { return WRONG_STATE }; + *mc = Mc::Connected(Connector {}); + ERR_OK } #[no_mangle] pub extern "C" fn send(fd: ConnectorFd, msg: *const c_void, len: usize, flags: c_int) -> isize { use MaybeConnector as Mc; // assuming _domain is AF_INET and _type is SOCK_DGRAM - let r = CONNECTOR_STORAGE.read().expect("Fd lock poisoned!"); - if let Some(maybe_conn) = r.fd_to_connector.get(&fd) { - let mc: &mut Mc = &mut maybe_conn.borrow_mut(); - match mc { - Mc::Bound(_local) => { - *mc = Mc::Connected(Connector {}); - 0 - } - _ => -1, // connector in wrong state - } - } else { - // no connector for this fd - return -2; - } + let r = if let Some(r) = CONNECTOR_STORAGE.read() { r } else { return FD_LOCK_POISONED }; + let mc = if let Some(mc) = r.fd_to_connector.get(&fd) { mc } else { return BAD_FD }; + let mc: &mut Mc = &mut maybe_conn.borrow_mut(); + let c = if let Mc::Connected(c) = mc { c } else { return WRONG_STATE }; + // TODO + ERR_OK }