diff --git a/src/ffi/pseudo_socket_api.rs b/src/ffi/pseudo_socket_api.rs index afb037c385bbcefa3484a89187a568f307c390c7..a68181547fc2b6b78588abac484aa98765139635 100644 --- a/src/ffi/pseudo_socket_api.rs +++ b/src/ffi/pseudo_socket_api.rs @@ -8,17 +8,13 @@ struct FdAllocator { next: Option, freed: Vec, } -enum ConnectorComplex { - Setup { - local: Option, - peer: Option, - }, - Communication { - // Invariant: connector in communication state; native has this putter and getter only. - connector: Connector, - putter: PortId, - getter: PortId, - }, +enum ConnectorComplexPhased { + Setup { local: Option, peer: Option }, + Communication { putter: PortId, getter: PortId }, +} +struct ConnectorComplex { + connector: Connector, + phased: ConnectorComplexPhased, } #[derive(Default)] struct CcMap { @@ -62,17 +58,12 @@ lazy_static::lazy_static! { } impl ConnectorComplex { fn try_become_connected(&mut self) { - match self { - ConnectorComplex::Setup { local: Some(local), peer: Some(peer) } => { + match self.phased { + ConnectorComplexPhased::Setup { local: Some(local), peer: Some(peer) } => { // complete setup - let mut connector = Connector::new( - Box::new(crate::DummyLogger), - crate::TRIVIAL_PD.clone(), - Connector::random_id(), - ); let [putter, getter] = connector.new_udp_mediator_component(*local, *peer).unwrap(); - connector.connect(None).unwrap(); - *self = ConnectorComplex::Communication { connector, putter, getter } + self.connector.connect(None).unwrap(); + self.phased = ConnectorComplexPhased::Communication { putter, getter } } _ => {} // setup incomplete } @@ -85,7 +76,14 @@ pub extern "C" fn rw_socket(_domain: c_int, _type: c_int) -> c_int { // get writer lock let mut w = if let Ok(w) = CC_MAP.write() { w } else { return LOCK_POISONED }; let fd = w.fd_allocator.alloc(); - let cc = ConnectorComplex::Setup { local: None, peer: None }; + let cc = ConnectorComplex { + connector: Connector::new( + Box::new(crate::DummyLogger), + crate::TRIVIAL_PD.clone(), + Connector::random_id(), + ), + phased: ConnectorComplexPhased::Setup { local: None, peer: None }, + }; w.fd_to_cc.insert(fd, RwLock::new(cc)); fd } @@ -112,10 +110,9 @@ pub unsafe extern "C" fn rw_bind(fd: c_int, addr: *const sockaddr, addr_len: soc let r = if let Ok(r) = CC_MAP.read() { r } else { return LOCK_POISONED }; let cc = if let Some(cc) = r.fd_to_cc.get(&fd) { cc } else { return BAD_FD }; let mut cc = if let Ok(cc) = cc.write() { cc } else { return LOCK_POISONED }; - let cc: &mut ConnectorComplex = &mut cc; - match cc { - ConnectorComplex::Communication { .. } => WRONG_STATE, - ConnectorComplex::Setup { local, .. } => { + match &cc.phased { + ConnectorComplexPhased::Communication { .. } => WRONG_STATE, + ConnectorComplexPhased::Setup { local, .. } => { *local = Some(addr); cc.try_become_connected(); ERR_OK @@ -137,8 +134,7 @@ pub unsafe extern "C" fn rw_connect( let r = if let Ok(r) = CC_MAP.read() { r } else { return LOCK_POISONED }; let cc = if let Some(cc) = r.fd_to_cc.get(&fd) { cc } else { return BAD_FD }; let mut cc = if let Ok(cc) = cc.write() { cc } else { return LOCK_POISONED }; - let cc: &mut ConnectorComplex = &mut cc; - match cc { + match &cc.phased { ConnectorComplex::Communication { .. } => WRONG_STATE, ConnectorComplex::Setup { peer, .. } => { *peer = Some(addr); @@ -159,13 +155,12 @@ pub unsafe extern "C" fn rw_send( let r = if let Ok(r) = CC_MAP.read() { r } else { return LOCK_POISONED as isize }; let cc = if let Some(cc) = r.fd_to_cc.get(&fd) { cc } else { return BAD_FD as isize }; let mut cc = if let Ok(cc) = cc.write() { cc } else { return LOCK_POISONED as isize }; - let cc: &mut ConnectorComplex = &mut cc; - match cc { + match &cc.phased { ConnectorComplex::Setup { .. } => WRONG_STATE as isize, ConnectorComplex::Communication { connector, putter, .. } => { let payload = payload_from_raw(bytes_ptr, bytes_len); - connector.put(*putter, payload).unwrap(); - connector.sync(None).unwrap(); + cc.connector.put(*putter, payload).unwrap(); + cc.connector.sync(None).unwrap(); bytes_len as isize } } @@ -182,13 +177,12 @@ pub unsafe extern "C" fn rw_recv( let r = if let Ok(r) = CC_MAP.read() { r } else { return LOCK_POISONED as isize }; let cc = if let Some(cc) = r.fd_to_cc.get(&fd) { cc } else { return BAD_FD as isize }; let mut cc = if let Ok(cc) = cc.write() { cc } else { return LOCK_POISONED as isize }; - let cc: &mut ConnectorComplex = &mut cc; - match cc { + match &cc.phased { ConnectorComplex::Setup { .. } => WRONG_STATE as isize, ConnectorComplex::Communication { connector, getter, .. } => { - connector.get(*getter).unwrap(); - connector.sync(None).unwrap(); - let slice = connector.gotten(*getter).unwrap().as_slice(); + cc.connector.get(*getter).unwrap(); + cc.connector.sync(None).unwrap(); + let slice = cc.connector.gotten(*getter).unwrap().as_slice(); if !bytes_ptr.is_null() { let cpy_msg_bytes = slice.len().min(bytes_len); std::ptr::copy_nonoverlapping(slice.as_ptr(), bytes_ptr as *mut u8, cpy_msg_bytes);