Changeset - 7e252436097c
[Not reviewed]
0 1 0
Christopher Esterhuyse - 5 years ago 2020-07-23 16:31:29
christopher.esterhuyse@gmail.com
pseudo-socket API mirrors the phases of the connector
1 file changed with 30 insertions and 36 deletions:
0 comments (0 inline, 0 general)
src/ffi/pseudo_socket_api.rs
Show inline comments
 
@@ -8,17 +8,13 @@ struct FdAllocator {
 
    next: Option<c_int>,
 
    freed: Vec<c_int>,
 
}
 
enum ConnectorComplex {
 
    Setup {
 
        local: Option<SocketAddr>,
 
        peer: Option<SocketAddr>,
 
    },
 
    Communication {
 
        // Invariant: connector in communication state; native has this putter and getter only.
 
        connector: Connector,
 
        putter: PortId,
 
        getter: PortId,
 
    },
 
enum ConnectorComplexPhased {
 
    Setup { local: Option<SocketAddr>, peer: Option<SocketAddr> },
 
    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);
0 comments (0 inline, 0 general)