Skip to content

Commit

Permalink
chore: refine feature flags (#1785)
Browse files Browse the repository at this point in the history
Removes dependencies between Tokio feature flags. For example, `process`
should not depend on `sync` simply because it uses the `mpsc` channel.
Instead, feature flags represent **public** APIs that become available
with the feature enabled. When the feature is not enabled, the
functionality is removed. If another Tokio component requires the
functionality, it is stays as `pub(crate)`.

The threaded scheduler is now exposed under `rt-threaded`. This feature
flag only enables the threaded scheduler and does not include I/O,
networking, or time. Those features must be explictly enabled.

A `full` feature flag is added that enables all features.

`stdin`, `stdout`, `stderr` are exposed under `io-std`.

Macros are used to scope code by feature flag.
  • Loading branch information
carllerche committed Nov 18, 2019
1 parent 13b6e99 commit 0d38936
Show file tree
Hide file tree
Showing 49 changed files with 1,091 additions and 914 deletions.
2 changes: 1 addition & 1 deletion tokio-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ quote = "1"
syn = { version = "1.0.3", features = ["full"] }

[dev-dependencies]
tokio = { version = "=0.2.0-alpha.6", path = "../tokio", default-features = false, features = ["rt-full"] }
tokio = { version = "=0.2.0-alpha.6", path = "../tokio" }

[package.metadata.docs.rs]
all-features = true
33 changes: 18 additions & 15 deletions tokio/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,30 +24,38 @@ categories = ["asynchronous", "network-programming"]
keywords = ["io", "async", "non-blocking", "futures"]

[features]
default = [
default = ["full"]

# enable everything
full = [
"blocking",
"dns",
"fs",
"io-driver",
"io-util",
"io",
"io-std",
"macros",
"net",
"process",
"rt-full",
"rt-core",
"rt-threaded",
"signal",
"stream",
"sync",
"time",
]

blocking = ["rt-core"]
dns = ["blocking"]
fs = ["blocking"]
io-driver = ["mio", "lazy_static", "sync"] # TODO: get rid of sync
dns = ["rt-core"]
fs = ["rt-core"]
io-driver = ["rt-core", "mio", "lazy_static"]
io-util = ["memchr"]
io = ["io-util", "blocking"]
# stdin, stdout, stderr
io-std = ["rt-core"]
macros = ["tokio-macros"]
net = ["dns", "tcp", "udp", "uds"]
process = [
"io-util", # TODO: Get rid of
"io-driver",
"libc",
"mio-named-pipes",
"signal",
Expand All @@ -58,14 +66,9 @@ process = [
]
# Includes basic task execution capabilities
rt-core = []
# TODO: rename this -> `rt-threaded`
rt-full = [
"macros",
rt-threaded = [
"num_cpus",
"net",
"rt-core",
"sync",
"time",
]
signal = [
"io-driver",
Expand All @@ -80,7 +83,7 @@ stream = ["futures-core"]
sync = ["fnv"]
test-util = []
tcp = ["io-driver"]
time = ["rt-core", "sync", "slab"]
time = ["rt-core", "slab"]
udp = ["io-driver"]
uds = ["io-driver", "mio-uds", "libc"]

Expand Down
12 changes: 8 additions & 4 deletions tokio/src/blocking/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
#![cfg_attr(not(feature = "blocking"), allow(dead_code, unused_imports))]

//! Perform blocking operations from an asynchronous context.

mod pool;
pub(crate) use self::pool::{spawn_blocking, BlockingPool, Spawner};
cfg_blocking_impl! {
mod pool;
pub(crate) use pool::{spawn_blocking, BlockingPool, Spawner};

mod schedule;
mod task;
mod schedule;
mod task;
}
20 changes: 12 additions & 8 deletions tokio/src/blocking/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,16 +116,20 @@ impl fmt::Debug for BlockingPool {

// ===== impl Spawner =====

impl Spawner {
#[cfg(feature = "rt-full")]
pub(crate) fn spawn_background<F>(&self, func: F)
where
F: FnOnce() + Send + 'static,
{
let task = task::background(BlockingTask::new(func));
self.schedule(task);

cfg_rt_threaded! {
impl Spawner {
pub(crate) fn spawn_background<F>(&self, func: F)
where
F: FnOnce() + Send + 'static,
{
let task = task::background(BlockingTask::new(func));
self.schedule(task);
}
}
}

impl Spawner {
/// Set the blocking pool for the duration of the closure
///
/// If a blocking pool is already set, it will be restored when the closure
Expand Down
30 changes: 17 additions & 13 deletions tokio/src/io/blocking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,14 @@ enum State<T> {
Busy(sys::Blocking<(io::Result<usize>, Buf, T)>),
}

impl<T> Blocking<T> {
#[cfg(feature = "io")]
pub(crate) fn new(inner: T) -> Blocking<T> {
Blocking {
inner: Some(inner),
state: State::Idle(Some(Buf::with_capacity(0))),
need_flush: false,
cfg_io_std! {
impl<T> Blocking<T> {
pub(crate) fn new(inner: T) -> Blocking<T> {
Blocking {
inner: Some(inner),
state: State::Idle(Some(Buf::with_capacity(0))),
need_flush: false,
}
}
}
}
Expand Down Expand Up @@ -264,12 +265,15 @@ impl Buf {
self.buf.clear();
res
}
}

#[cfg(feature = "fs")]
pub(crate) fn discard_read(&mut self) -> i64 {
let ret = -(self.bytes().len() as i64);
self.pos = 0;
self.buf.truncate(0);
ret
cfg_fs! {
impl Buf {
pub(crate) fn discard_read(&mut self) -> i64 {
let ret = -(self.bytes().len() as i64);
self.pos = 0;
self.buf.truncate(0);
ret
}
}
}
71 changes: 36 additions & 35 deletions tokio/src/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@
//! [`ErrorKind`]: enum.ErrorKind.html
//! [`Result`]: type.Result.html

#[cfg(any(feature = "io", feature = "fs"))]
pub(crate) mod blocking;
cfg_io_blocking! {
pub(crate) mod blocking;
}

mod async_buf_read;
pub use self::async_buf_read::AsyncBufRead;
Expand All @@ -48,43 +49,43 @@ pub use self::async_read::AsyncRead;
mod async_write;
pub use self::async_write::AsyncWrite;

#[cfg(feature = "io-util")]
pub mod split;
#[cfg(feature = "io-util")]
pub use self::split::split;
cfg_io_std! {
mod stderr;
pub use stderr::{stderr, Stderr};

#[cfg(feature = "io-util")]
mod util;
#[cfg(feature = "io-util")]
pub use self::util::{
copy, empty, repeat, sink, AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader, BufStream,
BufWriter, Copy, Empty, Lines, Repeat, Sink, Split, Take,
};
mod stdin;
pub use stdin::{stdin, Stdin};

#[cfg(feature = "io")]
mod stderr;
#[cfg(feature = "io")]
pub use self::stderr::{stderr, Stderr};
mod stdout;
pub use stdout::{stdout, Stdout};
}

#[cfg(feature = "io")]
mod stdin;
#[cfg(feature = "io")]
pub use self::stdin::{stdin, Stdin};
cfg_io_util! {
pub mod split;
pub use split::split;

#[cfg(feature = "io")]
mod stdout;
#[cfg(feature = "io")]
pub use self::stdout::{stdout, Stdout};
pub(crate) mod util;
pub use util::{
copy, empty, repeat, sink, AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader, BufStream,
BufWriter, Copy, Empty, Lines, Repeat, Sink, Split, Take,
};

// Re-export io::Error so that users don't have to deal
// with conflicts when `use`ing `tokio::io` and `std::io`.
#[cfg(feature = "io-util")]
pub use std::io::{Error, ErrorKind, Result};
// Re-export io::Error so that users don't have to deal with conflicts when
// `use`ing `tokio::io` and `std::io`.
pub use std::io::{Error, ErrorKind, Result};
}

cfg_not_io_util! {
cfg_process! {
pub(crate) mod util;
}
}

/// Types in this module can be mocked out in tests.
#[cfg(any(feature = "io", feature = "fs"))]
mod sys {
// TODO: don't rename
pub(crate) use crate::blocking::spawn_blocking as run;
pub(crate) use crate::task::JoinHandle as Blocking;
cfg_io_blocking! {
/// Types in this module can be mocked out in tests.
mod sys {
// TODO: don't rename
pub(crate) use crate::blocking::spawn_blocking as run;
pub(crate) use crate::task::JoinHandle as Blocking;
}
}
110 changes: 57 additions & 53 deletions tokio/src/io/util/mod.rs
Original file line number Diff line number Diff line change
@@ -1,71 +1,75 @@
mod async_buf_read_ext;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::async_buf_read_ext::AsyncBufReadExt;
#![allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411

mod async_read_ext;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::async_read_ext::AsyncReadExt;
cfg_io_util! {
mod async_buf_read_ext;
pub use async_buf_read_ext::AsyncBufReadExt;

mod async_write_ext;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::async_write_ext::AsyncWriteExt;
mod async_read_ext;
pub use async_read_ext::AsyncReadExt;

mod buf_reader;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::buf_reader::BufReader;
mod async_write_ext;
pub use async_write_ext::AsyncWriteExt;

mod buf_stream;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::buf_stream::BufStream;
mod buf_reader;
pub use buf_reader::BufReader;

mod buf_writer;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::buf_writer::BufWriter;
mod buf_stream;
pub use buf_stream::BufStream;

mod chain;
mod buf_writer;
pub use buf_writer::BufWriter;

mod copy;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::copy::{copy, Copy};
mod chain;

mod empty;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::empty::{empty, Empty};
mod copy;
pub use copy::{copy, Copy};

mod flush;
mod empty;
pub use empty::{empty, Empty};

mod lines;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::lines::Lines;
mod flush;

mod read;
mod read_exact;
mod read_line;
mod read_to_end;
mod read_to_string;
mod read_until;
mod lines;
pub use lines::Lines;

mod repeat;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::repeat::{repeat, Repeat};
mod read;
mod read_exact;
mod read_line;

mod shutdown;
mod read_to_end;
cfg_process! {
pub(crate) use read_to_end::read_to_end;
}

mod sink;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::sink::{sink, Sink};
mod read_to_string;
mod read_until;

mod split;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::split::Split;
mod repeat;
pub use repeat::{repeat, Repeat};

mod take;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::take::Take;
mod shutdown;

mod write;
mod write_all;
mod sink;
pub use sink::{sink, Sink};

// used by `BufReader` and `BufWriter`
// https://github.com/rust-lang/rust/blob/master/src/libstd/sys_common/io.rs#L1
const DEFAULT_BUF_SIZE: usize = 8 * 1024;
mod split;
pub use split::Split;

mod take;
pub use take::Take;

mod write;
mod write_all;

// used by `BufReader` and `BufWriter`
// https://github.com/rust-lang/rust/blob/master/src/libstd/sys_common/io.rs#L1
const DEFAULT_BUF_SIZE: usize = 8 * 1024;
}

cfg_not_io_util! {
cfg_process! {
mod read_to_end;
// Used by process
pub(crate) use read_to_end::read_to_end;
}
}

0 comments on commit 0d38936

Please sign in to comment.