mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-09-09 00:00:08 +02:00
Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c0746b6a30 | ||
|
|
b673eae342 | ||
|
|
b343767725 | ||
|
|
be620e913d | ||
|
|
ad942de2b7 | ||
|
|
4daeea8cad | ||
|
|
18efef7d3b | ||
|
|
d8cad13fd9 | ||
|
|
8ed06ef825 |
@@ -48,6 +48,7 @@ jobs:
|
||||
- check-readme
|
||||
- test-hyper
|
||||
- wasm32-unknown-unknown
|
||||
- wasm32-wasi
|
||||
steps:
|
||||
- run: exit 0
|
||||
|
||||
@@ -194,7 +195,7 @@ jobs:
|
||||
- name: Install Rust ${{ env.rust_nightly }}
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ env.rust_nightly }}
|
||||
toolchain: nightly-2022-07-10
|
||||
components: miri
|
||||
override: true
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
@@ -462,3 +463,37 @@ jobs:
|
||||
- name: test tokio
|
||||
run: wasm-pack test --node -- --features "macros sync"
|
||||
working-directory: tokio
|
||||
|
||||
wasm32-wasi:
|
||||
name: wasm32-wasi
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install Rust ${{ env.rust_stable }}
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ env.rust_stable }}
|
||||
override: true
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
|
||||
# Install dependencies
|
||||
- name: Install cargo-hack
|
||||
run: cargo install cargo-hack
|
||||
|
||||
- name: Install wasm32-wasi target
|
||||
run: rustup target add wasm32-wasi
|
||||
|
||||
- name: Install wasmtime
|
||||
run: cargo install wasmtime-cli
|
||||
|
||||
- name: Install cargo-wasi
|
||||
run: cargo install cargo-wasi
|
||||
|
||||
# TODO: Expand this when full WASI support lands.
|
||||
# Currently, this is a bare bones regression test
|
||||
# for features that work today with wasi.
|
||||
|
||||
- name: test tests-integration --features wasi-rt
|
||||
# TODO: this should become: `cargo hack wasi test --each-feature`
|
||||
run: cargo wasi test --test rt_yield --features wasi-rt
|
||||
working-directory: tests-integration
|
||||
|
||||
@@ -56,7 +56,7 @@ Make sure you activated the full features of the tokio crate on Cargo.toml:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
tokio = { version = "1.19.2", features = ["full"] }
|
||||
tokio = { version = "1.20.1", features = ["full"] }
|
||||
```
|
||||
Then, on your main.rs:
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ publish = false
|
||||
|
||||
[[bin]]
|
||||
name = "test-cat"
|
||||
required-features = ["rt-process-io-util"]
|
||||
|
||||
[[bin]]
|
||||
name = "test-mem"
|
||||
@@ -16,11 +17,30 @@ required-features = ["rt-net"]
|
||||
name = "test-process-signal"
|
||||
required-features = ["rt-process-signal"]
|
||||
|
||||
[[test]]
|
||||
name = "macros_main"
|
||||
|
||||
[[test]]
|
||||
name = "macros_pin"
|
||||
|
||||
[[test]]
|
||||
name = "macros_select"
|
||||
|
||||
[[test]]
|
||||
name = "rt_yield"
|
||||
required-features = ["rt", "macros", "sync"]
|
||||
|
||||
[features]
|
||||
rt-process-io-util = ["tokio/rt", "tokio/macros", "tokio/process", "tokio/io-util", "tokio/io-std"]
|
||||
# For mem check
|
||||
rt-net = ["tokio/rt", "tokio/rt-multi-thread", "tokio/net"]
|
||||
# For test-process-signal
|
||||
rt-process-signal = ["rt-net", "tokio/process", "tokio/signal"]
|
||||
# For testing wasi + rt/macros/sync features
|
||||
#
|
||||
# This is an explicit feature so we can use `cargo hack` testing single features
|
||||
# instead of all possible permutations.
|
||||
wasi-rt = ["rt", "macros", "sync"]
|
||||
|
||||
full = [
|
||||
"macros",
|
||||
|
||||
@@ -1,20 +1,14 @@
|
||||
//! A cat-like utility that can be used as a subprocess to test I/O
|
||||
//! stream communication.
|
||||
|
||||
use std::io;
|
||||
use std::io::Write;
|
||||
use tokio::io::AsyncWriteExt;
|
||||
|
||||
fn main() {
|
||||
let stdin = io::stdin();
|
||||
let mut stdout = io::stdout();
|
||||
let mut line = String::new();
|
||||
loop {
|
||||
line.clear();
|
||||
stdin.read_line(&mut line).unwrap();
|
||||
if line.is_empty() {
|
||||
break;
|
||||
}
|
||||
stdout.write_all(line.as_bytes()).unwrap();
|
||||
}
|
||||
stdout.flush().unwrap();
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn main() {
|
||||
let mut stdin = tokio::io::stdin();
|
||||
let mut stdout = tokio::io::stdout();
|
||||
|
||||
tokio::io::copy(&mut stdin, &mut stdout).await.unwrap();
|
||||
|
||||
stdout.flush().await.unwrap();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#![cfg(all(feature = "macros", feature = "rt"))]
|
||||
#![cfg(all(feature = "macros", feature = "rt-multi-thread"))]
|
||||
|
||||
#[tokio::main]
|
||||
async fn basic_main() -> usize {
|
||||
|
||||
@@ -8,12 +8,22 @@ use tokio_test::assert_ok;
|
||||
|
||||
use futures::future::{self, FutureExt};
|
||||
use std::convert::TryInto;
|
||||
use std::env;
|
||||
use std::io;
|
||||
use std::process::{ExitStatus, Stdio};
|
||||
|
||||
// so, we need to change this back as a test, but for now this doesn't work because of:
|
||||
// https://github.com/rust-lang/rust/pull/95469
|
||||
//
|
||||
// undo when this is closed: https://github.com/tokio-rs/tokio/issues/4802
|
||||
|
||||
// fn cat() -> Command {
|
||||
// let mut cmd = Command::new(std::env!("CARGO_BIN_EXE_test-cat"));
|
||||
// cmd.stdin(Stdio::piped()).stdout(Stdio::piped());
|
||||
// cmd
|
||||
// }
|
||||
|
||||
fn cat() -> Command {
|
||||
let mut cmd = Command::new(env!("CARGO_BIN_EXE_test-cat"));
|
||||
let mut cmd = Command::new("cat");
|
||||
cmd.stdin(Stdio::piped()).stdout(Stdio::piped());
|
||||
cmd
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
use tokio::sync::oneshot;
|
||||
use tokio::task;
|
||||
|
||||
async fn spawn_send() {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
|
||||
let task = tokio::spawn(async {
|
||||
for _ in 0..10 {
|
||||
task::yield_now().await;
|
||||
}
|
||||
|
||||
tx.send("done").unwrap();
|
||||
});
|
||||
|
||||
assert_eq!("done", rx.await.unwrap());
|
||||
task.await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn entry_point() {
|
||||
spawn_send().await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_macro() {
|
||||
spawn_send().await;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn main_macro() {
|
||||
entry_point();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn manual_rt() {
|
||||
let rt = tokio::runtime::Builder::new_current_thread()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
rt.block_on(async { spawn_send().await });
|
||||
}
|
||||
@@ -1,3 +1,57 @@
|
||||
# 1.20.1 (July 25, 2022)
|
||||
|
||||
### Fixed
|
||||
|
||||
- chore: fix version detection in build script ([#4860])
|
||||
|
||||
[#4860]: https://github.com/tokio-rs/tokio/pull/4860
|
||||
|
||||
# 1.20.0 (July 12, 2022)
|
||||
|
||||
### Added
|
||||
- tokio: add `track_caller` to public APIs ([#4772], [#4791], [#4793], [#4806], [#4808])
|
||||
- sync: Add `has_changed` method to `watch::Ref` ([#4758])
|
||||
|
||||
### Changed
|
||||
|
||||
- time: remove `src/time/driver/wheel/stack.rs` ([#4766])
|
||||
- rt: clean up arguments passed to basic scheduler ([#4767])
|
||||
- net: be more specific about winapi features ([#4764])
|
||||
- tokio: use const initialized thread locals where possible ([#4677])
|
||||
- task: various small improvements to LocalKey ([#4795])
|
||||
|
||||
### Documented
|
||||
|
||||
- fs: warn about performance pitfall ([#4762])
|
||||
- chore: fix spelling ([#4769])
|
||||
- sync: document spurious failures in oneshot ([#4777])
|
||||
- sync: add warning for watch in non-Send futures ([#4741])
|
||||
- chore: fix typo ([#4798])
|
||||
|
||||
### Unstable
|
||||
|
||||
- joinset: rename `join_one` to `join_next` ([#4755])
|
||||
- rt: unhandled panic config for current thread rt ([#4770])
|
||||
|
||||
[#4677]: https://github.com/tokio-rs/tokio/pull/4677
|
||||
[#4741]: https://github.com/tokio-rs/tokio/pull/4741
|
||||
[#4755]: https://github.com/tokio-rs/tokio/pull/4755
|
||||
[#4758]: https://github.com/tokio-rs/tokio/pull/4758
|
||||
[#4762]: https://github.com/tokio-rs/tokio/pull/4762
|
||||
[#4764]: https://github.com/tokio-rs/tokio/pull/4764
|
||||
[#4766]: https://github.com/tokio-rs/tokio/pull/4766
|
||||
[#4767]: https://github.com/tokio-rs/tokio/pull/4767
|
||||
[#4769]: https://github.com/tokio-rs/tokio/pull/4769
|
||||
[#4770]: https://github.com/tokio-rs/tokio/pull/4770
|
||||
[#4772]: https://github.com/tokio-rs/tokio/pull/4772
|
||||
[#4777]: https://github.com/tokio-rs/tokio/pull/4777
|
||||
[#4791]: https://github.com/tokio-rs/tokio/pull/4791
|
||||
[#4793]: https://github.com/tokio-rs/tokio/pull/4793
|
||||
[#4795]: https://github.com/tokio-rs/tokio/pull/4795
|
||||
[#4798]: https://github.com/tokio-rs/tokio/pull/4798
|
||||
[#4806]: https://github.com/tokio-rs/tokio/pull/4806
|
||||
[#4808]: https://github.com/tokio-rs/tokio/pull/4808
|
||||
|
||||
# 1.19.2 (June 6, 2022)
|
||||
|
||||
This release fixes another bug in `Notified::enable`. ([#4751])
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ name = "tokio"
|
||||
# - README.md
|
||||
# - Update CHANGELOG.md.
|
||||
# - Create "v1.0.x" git tag.
|
||||
version = "1.19.2"
|
||||
version = "1.20.1"
|
||||
edition = "2018"
|
||||
rust-version = "1.49"
|
||||
authors = ["Tokio Contributors <[email protected]>"]
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ Make sure you activated the full features of the tokio crate on Cargo.toml:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
tokio = { version = "1.19.2", features = ["full"] }
|
||||
tokio = { version = "1.20.1", features = ["full"] }
|
||||
```
|
||||
Then, on your main.rs:
|
||||
|
||||
|
||||
+38
-3
@@ -1,11 +1,38 @@
|
||||
use autocfg::AutoCfg;
|
||||
|
||||
const CONST_THREAD_LOCAL_PROBE: &str = r#"
|
||||
{
|
||||
thread_local! {
|
||||
static MY_PROBE: usize = const { 10 };
|
||||
}
|
||||
|
||||
MY_PROBE.with(|val| *val)
|
||||
}
|
||||
"#;
|
||||
|
||||
fn main() {
|
||||
let mut enable_const_thread_local = false;
|
||||
|
||||
match AutoCfg::new() {
|
||||
Ok(ac) => {
|
||||
// Const-initialized thread locals were stabilized in 1.59
|
||||
if ac.probe_rustc_version(1, 59) {
|
||||
autocfg::emit("tokio_const_thread_local")
|
||||
// These checks prefer to call only `probe_rustc_version` if that is
|
||||
// enough to determine whether the feature is supported. This is
|
||||
// because the `probe_expression` call involves a call to rustc,
|
||||
// which the `probe_rustc_version` call avoids.
|
||||
|
||||
// Const-initialized thread locals were stabilized in 1.59.
|
||||
if ac.probe_rustc_version(1, 60) {
|
||||
enable_const_thread_local = true;
|
||||
} else if ac.probe_rustc_version(1, 59) {
|
||||
// This compiler claims to be 1.59, but there are some nightly
|
||||
// compilers that claim to be 1.59 without supporting the
|
||||
// feature. Explicitly probe to check if code using them
|
||||
// compiles.
|
||||
//
|
||||
// The oldest nightly that supports the feature is 2021-12-06.
|
||||
if ac.probe_expression(CONST_THREAD_LOCAL_PROBE) {
|
||||
enable_const_thread_local = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,4 +46,12 @@ fn main() {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if !enable_const_thread_local {
|
||||
// To disable this feature on compilers that support it, you can
|
||||
// explicitly pass this flag with the following environment variable:
|
||||
//
|
||||
// RUSTFLAGS="--cfg tokio_no_const_thread_local"
|
||||
autocfg::emit("tokio_no_const_thread_local")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ pub async fn read_dir(path: impl AsRef<Path>) -> io::Result<ReadDir> {
|
||||
Ok(ReadDir(State::Idle(Some(std))))
|
||||
}
|
||||
|
||||
/// Reads the the entries in a directory.
|
||||
/// Reads the entries in a directory.
|
||||
///
|
||||
/// This struct is returned from the [`read_dir`] function of this module and
|
||||
/// will yield instances of [`DirEntry`]. Through a [`DirEntry`] information
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::future::Future;
|
||||
|
||||
cfg_rt! {
|
||||
#[track_caller]
|
||||
pub(crate) fn block_on<F: Future>(f: F) -> F::Output {
|
||||
let mut e = crate::runtime::enter::enter(false);
|
||||
e.block_on(f).unwrap()
|
||||
@@ -8,6 +9,7 @@ cfg_rt! {
|
||||
}
|
||||
|
||||
cfg_not_rt! {
|
||||
#[track_caller]
|
||||
pub(crate) fn block_on<F: Future>(f: F) -> F::Output {
|
||||
let mut park = crate::park::thread::CachedParkThread::new();
|
||||
park.block_on(f).unwrap()
|
||||
|
||||
@@ -10,12 +10,14 @@ macro_rules! thread_local {
|
||||
($($tts:tt)+) => { loom::thread_local!{ $($tts)+ } }
|
||||
}
|
||||
|
||||
#[cfg(all(tokio_const_thread_local, not(all(loom, test))))]
|
||||
#[cfg(not(tokio_no_const_thread_local))]
|
||||
#[cfg(not(all(loom, test)))]
|
||||
macro_rules! thread_local {
|
||||
($($tts:tt)+) => { ::std::thread_local!{ $($tts)+ } }
|
||||
}
|
||||
|
||||
#[cfg(all(not(tokio_const_thread_local), not(all(loom, test))))]
|
||||
#[cfg(tokio_no_const_thread_local)]
|
||||
#[cfg(not(all(loom, test)))]
|
||||
macro_rules! thread_local {
|
||||
($(#[$attrs:meta])* $vis:vis static $name:ident: $ty:ty = const { $expr:expr } $(;)?) => {
|
||||
::std::thread_local! {
|
||||
|
||||
@@ -31,6 +31,7 @@ cfg_rt! {
|
||||
|
||||
/// Marks the current thread as being within the dynamic extent of an
|
||||
/// executor.
|
||||
#[track_caller]
|
||||
pub(crate) fn enter(allow_blocking: bool) -> Enter {
|
||||
if let Some(enter) = try_enter(allow_blocking) {
|
||||
return enter;
|
||||
|
||||
@@ -384,6 +384,12 @@ pub struct Signal {
|
||||
/// * If the previous initialization of this specific signal failed.
|
||||
/// * If the signal is one of
|
||||
/// [`signal_hook::FORBIDDEN`](fn@signal_hook_registry::register#panics)
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is no current reactor set, or if the `rt`
|
||||
/// feature flag is not enabled.
|
||||
#[track_caller]
|
||||
pub fn signal(kind: SignalKind) -> io::Result<Signal> {
|
||||
let rx = signal_with_handle(kind, &Handle::current())?;
|
||||
|
||||
|
||||
@@ -182,6 +182,7 @@ cfg_rt! {
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is no current signal driver set.
|
||||
#[track_caller]
|
||||
pub(super) fn current() -> Self {
|
||||
crate::runtime::context::signal_handle().expect(
|
||||
"there is no signal driver running, must be called from the context of Tokio runtime",
|
||||
@@ -197,6 +198,7 @@ cfg_not_rt! {
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if there is no current signal driver set.
|
||||
#[track_caller]
|
||||
pub(super) fn current() -> Self {
|
||||
panic!(
|
||||
"there is no signal driver running, must be called from the context of Tokio runtime or with\
|
||||
|
||||
@@ -430,6 +430,7 @@ const MAX_RECEIVERS: usize = usize::MAX >> 2;
|
||||
///
|
||||
/// This will panic if `capacity` is equal to `0` or larger
|
||||
/// than `usize::MAX / 2`.
|
||||
#[track_caller]
|
||||
pub fn channel<T: Clone>(mut capacity: usize) -> (Sender<T>, Receiver<T>) {
|
||||
assert!(capacity > 0, "capacity is empty");
|
||||
assert!(capacity <= usize::MAX >> 1, "requested capacity too large");
|
||||
|
||||
@@ -105,6 +105,7 @@ pub struct Receiver<T> {
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[track_caller]
|
||||
pub fn channel<T>(buffer: usize) -> (Sender<T>, Receiver<T>) {
|
||||
assert!(buffer > 0, "mpsc bounded channel requires buffer > 0");
|
||||
let semaphore = (semaphore::Semaphore::new(buffer), buffer);
|
||||
@@ -281,6 +282,7 @@ impl<T> Receiver<T> {
|
||||
/// sync_code.join().unwrap()
|
||||
/// }
|
||||
/// ```
|
||||
#[track_caller]
|
||||
#[cfg(feature = "sync")]
|
||||
pub fn blocking_recv(&mut self) -> Option<T> {
|
||||
crate::future::block_on(self.recv())
|
||||
@@ -650,6 +652,7 @@ impl<T> Sender<T> {
|
||||
/// sync_code.join().unwrap()
|
||||
/// }
|
||||
/// ```
|
||||
#[track_caller]
|
||||
#[cfg(feature = "sync")]
|
||||
pub fn blocking_send(&self, value: T) -> Result<(), SendError<T>> {
|
||||
crate::future::block_on(self.send(value))
|
||||
|
||||
@@ -206,6 +206,7 @@ impl<T> UnboundedReceiver<T> {
|
||||
/// sync_code.join().unwrap();
|
||||
/// }
|
||||
/// ```
|
||||
#[track_caller]
|
||||
#[cfg(feature = "sync")]
|
||||
pub fn blocking_recv(&mut self) -> Option<T> {
|
||||
crate::future::block_on(self.recv())
|
||||
|
||||
@@ -411,6 +411,7 @@ impl<T: ?Sized> Mutex<T> {
|
||||
/// }
|
||||
///
|
||||
/// ```
|
||||
#[track_caller]
|
||||
#[cfg(feature = "sync")]
|
||||
pub fn blocking_lock(&self) -> MutexGuard<'_, T> {
|
||||
crate::future::block_on(self.lock())
|
||||
|
||||
@@ -1052,6 +1052,7 @@ impl<T> Receiver<T> {
|
||||
/// sync_code.join().unwrap();
|
||||
/// }
|
||||
/// ```
|
||||
#[track_caller]
|
||||
#[cfg(feature = "sync")]
|
||||
pub fn blocking_recv(self) -> Result<T, RecvError> {
|
||||
crate::future::block_on(self)
|
||||
|
||||
@@ -506,6 +506,7 @@ impl<T: ?Sized> RwLock<T> {
|
||||
/// assert!(rwlock.try_write().is_ok());
|
||||
/// }
|
||||
/// ```
|
||||
#[track_caller]
|
||||
#[cfg(feature = "sync")]
|
||||
pub fn blocking_read(&self) -> RwLockReadGuard<'_, T> {
|
||||
crate::future::block_on(self.read())
|
||||
@@ -840,6 +841,7 @@ impl<T: ?Sized> RwLock<T> {
|
||||
/// assert_eq!(*read_lock, 2);
|
||||
/// }
|
||||
/// ```
|
||||
#[track_caller]
|
||||
#[cfg(feature = "sync")]
|
||||
pub fn blocking_write(&self) -> RwLockWriteGuard<'_, T> {
|
||||
crate::future::block_on(self.write())
|
||||
|
||||
@@ -47,7 +47,7 @@ macro_rules! task_local {
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[cfg(tokio_const_thread_local)]
|
||||
#[cfg(not(tokio_no_const_thread_local))]
|
||||
#[macro_export]
|
||||
macro_rules! __task_local_inner {
|
||||
($(#[$attr:meta])* $vis:vis $name:ident, $t:ty) => {
|
||||
@@ -62,7 +62,7 @@ macro_rules! __task_local_inner {
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[cfg(not(tokio_const_thread_local))]
|
||||
#[cfg(tokio_no_const_thread_local)]
|
||||
#[macro_export]
|
||||
macro_rules! __task_local_inner {
|
||||
($(#[$attr:meta])* $vis:vis $name:ident, $t:ty) => {
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![cfg(feature = "full")]
|
||||
#![cfg(unix)]
|
||||
|
||||
use std::error::Error;
|
||||
use tokio::runtime::Builder;
|
||||
use tokio::signal::unix::{signal, SignalKind};
|
||||
|
||||
mod support {
|
||||
pub mod panic;
|
||||
}
|
||||
use support::panic::test_panic;
|
||||
|
||||
#[test]
|
||||
fn signal_panic_caller() -> Result<(), Box<dyn Error>> {
|
||||
let panic_location_file = test_panic(|| {
|
||||
let rt = Builder::new_current_thread().build().unwrap();
|
||||
|
||||
rt.block_on(async {
|
||||
let kind = SignalKind::from_raw(-1);
|
||||
let _ = signal(kind);
|
||||
});
|
||||
});
|
||||
|
||||
// The panic location should be in this file
|
||||
assert_eq!(&panic_location_file.unwrap(), file!());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![cfg(feature = "full")]
|
||||
|
||||
use std::error::Error;
|
||||
use tokio::{
|
||||
runtime::{Builder, Runtime},
|
||||
sync::{broadcast, mpsc, oneshot, Mutex, RwLock},
|
||||
};
|
||||
|
||||
mod support {
|
||||
pub mod panic;
|
||||
}
|
||||
use support::panic::test_panic;
|
||||
|
||||
#[test]
|
||||
fn broadcast_channel_panic_caller() -> Result<(), Box<dyn Error>> {
|
||||
let panic_location_file = test_panic(|| {
|
||||
let (_, _) = broadcast::channel::<u32>(0);
|
||||
});
|
||||
|
||||
// The panic location should be in this file
|
||||
assert_eq!(&panic_location_file.unwrap(), file!());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mutex_blocking_lock_panic_caller() -> Result<(), Box<dyn Error>> {
|
||||
let panic_location_file = test_panic(|| {
|
||||
let rt = basic();
|
||||
rt.block_on(async {
|
||||
let mutex = Mutex::new(5_u32);
|
||||
mutex.blocking_lock();
|
||||
});
|
||||
});
|
||||
|
||||
// The panic location should be in this file
|
||||
assert_eq!(&panic_location_file.unwrap(), file!());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn oneshot_blocking_recv_panic_caller() -> Result<(), Box<dyn Error>> {
|
||||
let panic_location_file = test_panic(|| {
|
||||
let rt = basic();
|
||||
rt.block_on(async {
|
||||
let (_tx, rx) = oneshot::channel::<u8>();
|
||||
let _ = rx.blocking_recv();
|
||||
});
|
||||
});
|
||||
|
||||
// The panic location should be in this file
|
||||
assert_eq!(&panic_location_file.unwrap(), file!());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rwlock_with_max_readers_panic_caller() -> Result<(), Box<dyn Error>> {
|
||||
let panic_location_file = test_panic(|| {
|
||||
let _ = RwLock::<u8>::with_max_readers(0, (u32::MAX >> 3) + 1);
|
||||
});
|
||||
|
||||
// The panic location should be in this file
|
||||
assert_eq!(&panic_location_file.unwrap(), file!());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rwlock_blocking_read_panic_caller() -> Result<(), Box<dyn Error>> {
|
||||
let panic_location_file = test_panic(|| {
|
||||
let rt = basic();
|
||||
rt.block_on(async {
|
||||
let lock = RwLock::<u8>::new(0);
|
||||
let _ = lock.blocking_read();
|
||||
});
|
||||
});
|
||||
|
||||
// The panic location should be in this file
|
||||
assert_eq!(&panic_location_file.unwrap(), file!());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rwlock_blocking_write_panic_caller() -> Result<(), Box<dyn Error>> {
|
||||
let panic_location_file = test_panic(|| {
|
||||
let rt = basic();
|
||||
rt.block_on(async {
|
||||
let lock = RwLock::<u8>::new(0);
|
||||
let _ = lock.blocking_write();
|
||||
});
|
||||
});
|
||||
|
||||
// The panic location should be in this file
|
||||
assert_eq!(&panic_location_file.unwrap(), file!());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mpsc_bounded_channel_panic_caller() -> Result<(), Box<dyn Error>> {
|
||||
let panic_location_file = test_panic(|| {
|
||||
let (_, _) = mpsc::channel::<u8>(0);
|
||||
});
|
||||
|
||||
// The panic location should be in this file
|
||||
assert_eq!(&panic_location_file.unwrap(), file!());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mpsc_bounded_receiver_blocking_recv_panic_caller() -> Result<(), Box<dyn Error>> {
|
||||
let panic_location_file = test_panic(|| {
|
||||
let rt = basic();
|
||||
let (_tx, mut rx) = mpsc::channel::<u8>(1);
|
||||
rt.block_on(async {
|
||||
let _ = rx.blocking_recv();
|
||||
});
|
||||
});
|
||||
|
||||
// The panic location should be in this file
|
||||
assert_eq!(&panic_location_file.unwrap(), file!());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mpsc_bounded_sender_blocking_send_panic_caller() -> Result<(), Box<dyn Error>> {
|
||||
let panic_location_file = test_panic(|| {
|
||||
let rt = basic();
|
||||
let (tx, _rx) = mpsc::channel::<u8>(1);
|
||||
rt.block_on(async {
|
||||
let _ = tx.blocking_send(3);
|
||||
});
|
||||
});
|
||||
|
||||
// The panic location should be in this file
|
||||
assert_eq!(&panic_location_file.unwrap(), file!());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mpsc_unbounded_receiver_blocking_recv_panic_caller() -> Result<(), Box<dyn Error>> {
|
||||
let panic_location_file = test_panic(|| {
|
||||
let rt = basic();
|
||||
let (_tx, mut rx) = mpsc::unbounded_channel::<u8>();
|
||||
rt.block_on(async {
|
||||
let _ = rx.blocking_recv();
|
||||
});
|
||||
});
|
||||
|
||||
// The panic location should be in this file
|
||||
assert_eq!(&panic_location_file.unwrap(), file!());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn basic() -> Runtime {
|
||||
Builder::new_current_thread().enable_all().build().unwrap()
|
||||
}
|
||||
Reference in New Issue
Block a user