diff --git a/Cargo.toml b/Cargo.toml index e5d19f0dd2c5e3db8d304dc979408f8f9c2fba95..258a30287cfdafbbc1e850669b231fda1cbb8fe4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,7 @@ lazy_static = "1.4.0" crate-type = ["cdylib"] [features] -default = ["ffi", "session_optimization", "ffi_pseudo_socket_api"] +default = ["ffi", "session_optimization"] ffi = [] # see src/ffi/mod.rs ffi_pseudo_socket_api = ["ffi", "libc", "os_socketaddr"]# see src/ffi/pseudo_socket_api.rs endpoint_logging = [] # see src/macros.rs diff --git a/src/ffi/pseudo_socket_api.rs b/src/ffi/pseudo_socket_api.rs index 254956b3749f660f6a2d9996d9fa43dc03fd457f..8d64015bcf1b3e0137e59ea38f415c0ce3c088d2 100644 --- a/src/ffi/pseudo_socket_api.rs +++ b/src/ffi/pseudo_socket_api.rs @@ -1,7 +1,7 @@ use super::*; -use libc::{sockaddr, socklen_t}; use core::ops::DerefMut; +use libc::{sockaddr, socklen_t}; use std::{collections::HashMap, ffi::c_void, net::SocketAddr, os::raw::c_int, sync::RwLock}; /////////////////////////////////////////////////////////////////// @@ -14,6 +14,7 @@ enum ConnectorComplexPhased { Communication { putter: PortId, getter: PortId }, } struct ConnectorComplex { + // invariant: .connector.phased and .phased are variants Setup/Communication in lockstep. connector: Connector, phased: ConnectorComplexPhased, } @@ -33,10 +34,8 @@ unsafe fn libc_to_std_sockaddr(addr: *const sockaddr, addr_len: socklen_t) -> Op } impl Default for FdAllocator { fn default() -> Self { - Self { - next: Some(0), // positive values used only - freed: vec![], - } + // negative FDs aren't used s.t. they are available for error signalling + Self { next: Some(0), freed: vec![] } } } impl FdAllocator { @@ -62,7 +61,8 @@ impl ConnectorComplex { match self.phased { ConnectorComplexPhased::Setup { local: Some(local), peer: Some(peer) } => { // complete setup - let [putter, getter] = self.connector.new_udp_mediator_component(local, peer).unwrap(); + let [putter, getter] = + self.connector.new_udp_mediator_component(local, peer).unwrap(); self.connector.connect(None).unwrap(); self.phased = ConnectorComplexPhased::Communication { putter, getter } } diff --git a/src/runtime/mod.rs b/src/runtime/mod.rs index ee259424adb10d50f7f3b07dc3a4ffbd62bf878a..4ff25bc6eefbe4e62f889614e0892c06528cbde5 100644 --- a/src/runtime/mod.rs +++ b/src/runtime/mod.rs @@ -379,6 +379,17 @@ impl Drop for Connector { } } impl Connector { + pub fn is_connected(&self) -> bool { + // If designed for Rust usage, connectors would be exposed as an enum type from the start. + // consequently, this "phased" business would also include connector variants and this would + // get a lot closer to the connector impl. itself. + // Instead, the C-oriented implementation doesn't distinguish connector states as types, + // and distinguish them as enum variants instead + match self.phased { + ConnectorPhased::Setup(..) => false, + ConnectorPhased::Communication(..) => true, + } + } pub(crate) fn random_id() -> ConnectorId { type Bytes8 = [u8; std::mem::size_of::()]; unsafe {