121 lines
3.7 KiB
Rust
121 lines
3.7 KiB
Rust
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
use crate::{
|
|
events::{IoEvents, Observer},
|
|
fs::utils::{Channel, Consumer, Producer},
|
|
net::socket::{unix::addr::UnixSocketAddrBound, SockShutdownCmd},
|
|
prelude::*,
|
|
process::signal::{Pollee, Poller},
|
|
};
|
|
|
|
pub(super) struct Connected {
|
|
addr: Option<UnixSocketAddrBound>,
|
|
peer_addr: Option<UnixSocketAddrBound>,
|
|
reader: Consumer<u8>,
|
|
writer: Producer<u8>,
|
|
}
|
|
|
|
impl Connected {
|
|
pub(super) fn new_pair(
|
|
addr: Option<UnixSocketAddrBound>,
|
|
peer_addr: Option<UnixSocketAddrBound>,
|
|
reader_pollee: Option<Pollee>,
|
|
writer_pollee: Option<Pollee>,
|
|
) -> (Connected, Connected) {
|
|
let (writer_peer, reader_this) =
|
|
Channel::with_capacity_and_pollees(DEFAULT_BUF_SIZE, None, reader_pollee).split();
|
|
let (writer_this, reader_peer) =
|
|
Channel::with_capacity_and_pollees(DEFAULT_BUF_SIZE, writer_pollee, None).split();
|
|
|
|
let this = Connected {
|
|
addr: addr.clone(),
|
|
peer_addr: peer_addr.clone(),
|
|
reader: reader_this,
|
|
writer: writer_this,
|
|
};
|
|
let peer = Connected {
|
|
addr: peer_addr,
|
|
peer_addr: addr,
|
|
reader: reader_peer,
|
|
writer: writer_peer,
|
|
};
|
|
|
|
(this, peer)
|
|
}
|
|
|
|
pub(super) fn addr(&self) -> Option<&UnixSocketAddrBound> {
|
|
self.addr.as_ref()
|
|
}
|
|
|
|
pub(super) fn peer_addr(&self) -> Option<&UnixSocketAddrBound> {
|
|
self.peer_addr.as_ref()
|
|
}
|
|
|
|
pub(super) fn try_read(&self, buf: &mut [u8]) -> Result<usize> {
|
|
let mut writer = VmWriter::from(buf).to_fallible();
|
|
self.reader.try_read(&mut writer)
|
|
}
|
|
|
|
pub(super) fn try_write(&self, buf: &[u8]) -> Result<usize> {
|
|
let mut reader = VmReader::from(buf).to_fallible();
|
|
self.writer.try_write(&mut reader)
|
|
}
|
|
|
|
pub(super) fn shutdown(&self, cmd: SockShutdownCmd) -> Result<()> {
|
|
if cmd.shut_read() {
|
|
self.reader.shutdown();
|
|
}
|
|
|
|
if cmd.shut_write() {
|
|
self.writer.shutdown();
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub(super) fn poll(&self, mask: IoEvents, mut poller: Option<&mut Poller>) -> IoEvents {
|
|
// Note that `mask | IoEvents::ALWAYS_POLL` contains all the events we care about.
|
|
let reader_events = self.reader.poll(mask, poller.as_deref_mut());
|
|
let writer_events = self.writer.poll(mask, poller);
|
|
|
|
let mut events = IoEvents::empty();
|
|
|
|
if reader_events.contains(IoEvents::HUP) {
|
|
// The socket is shut down in one direction: the remote socket has shut down for
|
|
// writing or the local socket has shut down for reading.
|
|
events |= IoEvents::RDHUP | IoEvents::IN;
|
|
|
|
if writer_events.contains(IoEvents::ERR) {
|
|
// The socket is shut down in both directions. Neither reading nor writing is
|
|
// possible.
|
|
events |= IoEvents::HUP;
|
|
}
|
|
}
|
|
|
|
events |= (reader_events & IoEvents::IN) | (writer_events & IoEvents::OUT);
|
|
|
|
events & (mask | IoEvents::ALWAYS_POLL)
|
|
}
|
|
|
|
pub(super) fn register_observer(
|
|
&self,
|
|
observer: Weak<dyn Observer<IoEvents>>,
|
|
mask: IoEvents,
|
|
) -> Result<()> {
|
|
self.reader.register_observer(observer.clone(), mask)?;
|
|
self.writer.register_observer(observer, mask)?;
|
|
Ok(())
|
|
}
|
|
|
|
pub(super) fn unregister_observer(
|
|
&self,
|
|
observer: &Weak<dyn Observer<IoEvents>>,
|
|
) -> Option<Weak<dyn Observer<IoEvents>>> {
|
|
let reader_observer = self.reader.unregister_observer(observer);
|
|
let writer_observer = self.writer.unregister_observer(observer);
|
|
reader_observer.or(writer_observer)
|
|
}
|
|
}
|
|
|
|
const DEFAULT_BUF_SIZE: usize = 65536;
|