Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port MIO library to Solaris OS #1263

Closed
wants to merge 10 commits into from
13 changes: 11 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ publish = false
default = []
# Include implementations of I/O source readiness polling.
os-poll = []
# Enable epoll(7) backend for I/O source polling.
os-epoll = ["os-poll"]
# Enable kqueue(7) backend for I/O source polling.
os-kqueue = ["os-poll"]
# Enable epoll(7) or kqueue(7) backend for I/O source polling.
os-poll-accel = ["os-epoll", "os-kqueue"]
# Include adapters for underlying OS I/O sources.
# Note: This is currently only supported on Unix and provides `SourceFd`
os-util = []
Expand All @@ -42,6 +48,9 @@ guide = []
[dependencies]
log = "0.4.8"

[target.'cfg(target_os = "macos")'.dependencies]
cvt = "0.1"

[target.'cfg(unix)'.dependencies]
libc = "0.2.62"

Expand All @@ -61,8 +70,8 @@ rustdoc-args = ["--cfg", "docsrs"]

[[example]]
name = "tcp_server"
required-features = ["os-poll", "tcp"]
required-features = ["os-poll-accel", "tcp"]

[[example]]
name = "udp_server"
required-features = ["os-poll", "udp"]
required-features = ["os-poll-accel", "udp"]
8 changes: 8 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ jobs:
displayName: Test --release
cmd: test --release

# Stable --release (POSIX poll(2))
- template: ci/azure-test-stable.yml
parameters:
name: stable_release_posix_poll
displayName: Test --release (using POSIX poll(2) I/O Selector)
cmd: test --release
posix_poll: true

# Nightly
- template: ci/azure-test-stable.yml
parameters:
Expand Down
15 changes: 11 additions & 4 deletions ci/azure-test-stable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,17 @@ jobs:
cargo hack check --feature-powerset --skip guide
displayName: Check feature powerset

- script: cargo ${{ parameters.cmd }} --all-features
displayName: cargo ${{ parameters.cmd }} --all-features
env:
CI: "True"
- ${{ if eq(parameters.posix_poll, false) }}:
- script: cargo ${{ parameters.cmd }} --all-features
displayName: cargo ${{ parameters.cmd }} --all-features
env:
CI: "True"

- ${{ if eq(parameters.posix_poll, true) }}:
- script: cargo ${{ parameters.cmd }} --features "os-poll os-util tcp udp uds"
displayName: cargo ${{ parameters.cmd }} --features "os-poll os-util tcp udp uds"
env:
CI: "True"

- ${{ if eq(parameters.cmd, 'test') }}:
- script: cargo doc --no-deps
Expand Down
145 changes: 85 additions & 60 deletions src/io_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::os::windows::io::AsRawSocket;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::{fmt, io};

#[cfg(any(unix, debug_assertions))]
#[cfg(debug_assertions)]
use crate::poll;
use crate::sys::IoSourceState;
use crate::{event, Interest, Registry, Token};
Expand Down Expand Up @@ -129,72 +129,97 @@ impl<T> DerefMut for IoSource<T> {
}
}

#[cfg(unix)]
impl<T> event::Source for IoSource<T>
where
T: AsRawFd,
{
fn register(
&mut self,
registry: &Registry,
token: Token,
interests: Interest,
) -> io::Result<()> {
#[cfg(debug_assertions)]
self.selector_id.associate(registry)?;
poll::selector(registry).register(self.inner.as_raw_fd(), token, interests)
}
cfg_epoll_or_kqueue! {
#[cfg(not(debug_assertions))]
use crate::poll;
impl<T> event::Source for IoSource<T>
where
T: AsRawFd,
{
fn register(
&mut self,
registry: &Registry,
token: Token,
interests: Interest,
) -> io::Result<()> {
#[cfg(debug_assertions)]
self.selector_id.associate(registry)?;
poll::selector(registry).register(self.inner.as_raw_fd(), token,
interests)
}

fn reregister(
&mut self,
registry: &Registry,
token: Token,
interests: Interest,
) -> io::Result<()> {
#[cfg(debug_assertions)]
self.selector_id.check_association(registry)?;
poll::selector(registry).reregister(self.inner.as_raw_fd(), token, interests)
}
fn reregister(
&mut self,
registry: &Registry,
token: Token,
interests: Interest,
) -> io::Result<()> {
#[cfg(debug_assertions)]
self.selector_id.check_association(registry)?;
poll::selector(registry).reregister(self.inner.as_raw_fd(), token,
interests)
}

fn deregister(&mut self, registry: &Registry) -> io::Result<()> {
#[cfg(debug_assertions)]
self.selector_id.remove_association(registry)?;
poll::selector(registry).deregister(self.inner.as_raw_fd())
fn deregister(&mut self, registry: &Registry) -> io::Result<()> {
#[cfg(debug_assertions)]
self.selector_id.remove_association(registry)?;
poll::selector(registry).deregister(self.inner.as_raw_fd())
}
}
}

#[cfg(windows)]
impl<T> event::Source for IoSource<T>
where
T: AsRawSocket,
{
fn register(
&mut self,
registry: &Registry,
token: Token,
interests: Interest,
) -> io::Result<()> {
#[cfg(debug_assertions)]
self.selector_id.associate(registry)?;
self.state
.register(registry, token, interests, self.inner.as_raw_socket())
}
cfg_neither_epoll_nor_kqueue! {
#[cfg(not(windows))]
pub trait AsRawFdOrSocket: AsRawFd {}
#[cfg(not(windows))]
impl<T: AsRawFd> AsRawFdOrSocket for T {}
#[cfg(windows)]
pub trait AsRawFdOrSocket: AsRawSocket {}
#[cfg(windows)]
impl<T: AsRawSocket> AsRawFdOrSocket for T {}

fn reregister(
&mut self,
registry: &Registry,
token: Token,
interests: Interest,
) -> io::Result<()> {
#[cfg(debug_assertions)]
self.selector_id.check_association(registry)?;
self.state.reregister(registry, token, interests)
}
impl<T> event::Source for IoSource<T>
where
T: AsRawFdOrSocket,
{
fn register(
&mut self,
registry: &Registry,
token: Token,
interests: Interest,
) -> io::Result<()> {
#[cfg(debug_assertions)]
self.selector_id.associate(registry)?;
#[cfg(windows)]
{
self.state
.register(registry, token, interests,
self.inner.as_raw_socket())
}
#[cfg(not(windows))]
{
self.state
.register(registry, token, interests,
self.inner.as_raw_fd())
}
}

fn deregister(&mut self, _registry: &Registry) -> io::Result<()> {
#[cfg(debug_assertions)]
self.selector_id.remove_association(_registry)?;
self.state.deregister()
fn reregister(
&mut self,
registry: &Registry,
token: Token,
interests: Interest,
) -> io::Result<()> {
#[cfg(debug_assertions)]
self.selector_id.check_association(registry)?;
self.state.reregister(registry, token, interests)
}

fn deregister(&mut self, _registry: &Registry) -> io::Result<()> {
#[cfg(debug_assertions)]
self.selector_id.remove_association(_registry)?;
self.state.deregister()
}
}
}

Expand Down
141 changes: 141 additions & 0 deletions src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,144 @@ macro_rules! cfg_any_os_util {
)*
}
}

/// OS supports epoll(7) interface
macro_rules! cfg_epoll {
($($item:item)*) => {
$(
#[cfg(all(
any(
target_os = "linux",
target_os = "android",
target_os = "illumos",
),
feature = "os-epoll",
))]
$item
)*
}
}

/// OS supports kqueue(2) interface
macro_rules! cfg_kqueue {
($($item:item)*) => {
$(
#[cfg(all(
any(
target_os = "dragonfly",
target_os = "freebsd",
target_os = "ios",
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd",
),
feature = "os-kqueue"
))]
$item
)*
}
}

/// OS supports either epoll(7) or kqueue(2) interface
macro_rules! cfg_epoll_or_kqueue {
($($item:item)*) => {
$(
#[cfg(any(
all(
any(
target_os = "linux",
target_os = "android",
target_os = "illumos",
),
feature = "os-epoll",
),
all(
any(
target_os = "dragonfly",
target_os = "freebsd",
target_os = "ios",
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd",
),
feature = "os-kqueue"
)
))]
$item
)*
}
}

/// OS neither supports epoll(7) nor kqueue(2) interfaces
macro_rules! cfg_neither_epoll_nor_kqueue {
($($item:item)*) => {
$(
#[cfg(not(any(
all(
any(
target_os = "linux",
target_os = "android",
target_os = "illumos",
),
feature = "os-epoll",
),
all(
any(
target_os = "dragonfly",
target_os = "freebsd",
target_os = "ios",
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd",
),
feature = "os-kqueue"
)
)))]
$item
)*
}
}

/// Enable Waker backed by kqueue(2) interface
macro_rules! cfg_kqueue_waker {
($($item:item)*) => {
$(
#[cfg(all(
any(
target_os = "freebsd",
target_os = "ios",
target_os = "macos",
),
feature = "os-kqueue"
))]
$item
)*
}
}

/// Enable Waker backed by pipe(2) interface
macro_rules! cfg_pipe_waker {
($($item:item)*) => {
$(
#[cfg(not(any(
all(
any(
target_os = "linux",
target_os = "android",
target_os = "illumos",
),
feature = "os-epoll",
),
all(
any(
target_os = "freebsd",
target_os = "ios",
target_os = "macos",
),
feature = "os-kqueue"
)
)))]
$item
)*
}
}
2 changes: 1 addition & 1 deletion src/net/uds/listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl UnixListener {
/// The call is responsible for ensuring that the listening socket is in
/// non-blocking mode.
pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
sys::uds::listener::accept(&self.inner)
self.inner.do_io(|inner| sys::uds::listener::accept(inner))
}

/// Returns the local socket address of this listener.
Expand Down
Loading