diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/mio-0.6.23/src/sys/fuchsia/mod.rs | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream.tar.xz firefox-esr-upstream.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/mio-0.6.23/src/sys/fuchsia/mod.rs')
-rw-r--r-- | third_party/rust/mio-0.6.23/src/sys/fuchsia/mod.rs | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/third_party/rust/mio-0.6.23/src/sys/fuchsia/mod.rs b/third_party/rust/mio-0.6.23/src/sys/fuchsia/mod.rs new file mode 100644 index 0000000000..10728fc8dc --- /dev/null +++ b/third_party/rust/mio-0.6.23/src/sys/fuchsia/mod.rs @@ -0,0 +1,177 @@ +use {io, Ready, PollOpt}; +use libc; +use zircon; +use std::mem; +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; +use std::ops::{Deref, DerefMut}; +use std::os::unix::io::RawFd; + +mod awakener; +mod handles; +mod eventedfd; +mod net; +mod ready; +mod selector; + +use self::eventedfd::{EventedFd, EventedFdInner}; +use self::ready::assert_fuchsia_ready_repr; + +pub use self::awakener::Awakener; +pub use self::handles::EventedHandle; +pub use self::net::{TcpListener, TcpStream, UdpSocket}; +pub use self::selector::{Events, Selector}; +pub use self::ready::{FuchsiaReady, zx_signals_t}; + +// Set non-blocking (workaround since the std version doesn't work in fuchsia) +// TODO: fix the std version and replace this +pub fn set_nonblock(fd: RawFd) -> io::Result<()> { + cvt(unsafe { libc::fcntl(fd, libc::F_SETFL, libc::O_NONBLOCK) }).map(|_| ()) +} + +/// Workaround until fuchsia's recv_from is fixed +unsafe fn recv_from(fd: RawFd, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { + let flags = 0; + + let n = cvt( + libc::recv(fd, + buf.as_mut_ptr() as *mut libc::c_void, + buf.len(), + flags) + )?; + + // random address-- we don't use it + let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080); + Ok((n as usize, addr)) +} + +mod sys { + #![allow(non_camel_case_types)] + use std::os::unix::io::RawFd; + pub use zircon_sys::{zx_handle_t, zx_signals_t}; + + // 17 fn pointers we don't need for mio :) + pub type fdio_ops_t = [usize; 17]; + + pub type atomic_int_fast32_t = usize; // TODO: https://github.com/rust-lang/libc/issues/631 + + #[repr(C)] + pub struct fdio_t { + pub ops: *const fdio_ops_t, + pub magic: u32, + pub refcount: atomic_int_fast32_t, + pub dupcount: u32, + pub flags: u32, + } + + #[link(name="fdio")] + extern { + pub fn __fdio_fd_to_io(fd: RawFd) -> *const fdio_t; + pub fn __fdio_release(io: *const fdio_t); + + pub fn __fdio_wait_begin( + io: *const fdio_t, + events: u32, + handle_out: &mut zx_handle_t, + signals_out: &mut zx_signals_t, + ); + pub fn __fdio_wait_end( + io: *const fdio_t, + signals: zx_signals_t, + events_out: &mut u32, + ); + } +} + +fn epoll_event_to_ready(epoll: u32) -> Ready { + let epoll = epoll as i32; // casts the bits directly + let mut kind = Ready::empty(); + + if (epoll & libc::EPOLLIN) != 0 || (epoll & libc::EPOLLPRI) != 0 { + kind = kind | Ready::readable(); + } + + if (epoll & libc::EPOLLOUT) != 0 { + kind = kind | Ready::writable(); + } + + kind + + /* TODO: support? + // EPOLLHUP - Usually means a socket error happened + if (epoll & libc::EPOLLERR) != 0 { + kind = kind | UnixReady::error(); + } + + if (epoll & libc::EPOLLRDHUP) != 0 || (epoll & libc::EPOLLHUP) != 0 { + kind = kind | UnixReady::hup(); + } + */ +} + +fn poll_opts_to_wait_async(poll_opts: PollOpt) -> zircon::WaitAsyncOpts { + if poll_opts.is_oneshot() { + zircon::WaitAsyncOpts::Once + } else { + zircon::WaitAsyncOpts::Repeating + } +} + +trait IsMinusOne { + fn is_minus_one(&self) -> bool; +} + +impl IsMinusOne for i32 { + fn is_minus_one(&self) -> bool { *self == -1 } +} + +impl IsMinusOne for isize { + fn is_minus_one(&self) -> bool { *self == -1 } +} + +fn cvt<T: IsMinusOne>(t: T) -> ::io::Result<T> { + use std::io; + + if t.is_minus_one() { + Err(io::Error::last_os_error()) + } else { + Ok(t) + } +} + +/// Utility type to prevent the type inside of it from being dropped. +#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] +struct DontDrop<T>(Option<T>); + +impl<T> DontDrop<T> { + fn new(t: T) -> DontDrop<T> { + DontDrop(Some(t)) + } + + fn inner_ref(&self) -> &T { + self.0.as_ref().unwrap() + } + + fn inner_mut(&mut self) -> &mut T { + self.0.as_mut().unwrap() + } +} + +impl<T> Deref for DontDrop<T> { + type Target = T; + fn deref(&self) -> &Self::Target { + self.inner_ref() + } +} + +impl<T> DerefMut for DontDrop<T> { + fn deref_mut(&mut self) -> &mut Self::Target { + self.inner_mut() + } +} + +impl<T> Drop for DontDrop<T> { + fn drop(&mut self) { + let inner = self.0.take(); + mem::forget(inner); + } +} |