diff options
Diffstat (limited to 'vendor/flume')
35 files changed, 0 insertions, 15554 deletions
diff --git a/vendor/flume/.cargo-checksum.json b/vendor/flume/.cargo-checksum.json deleted file mode 100644 index b254421..0000000 --- a/vendor/flume/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"CHANGELOG.md":"378edfec4dde51dee9c0d1e8285d88b3d218cb9b8b42ffa3e27405661c23b0b6","Cargo.lock":"cc14608e4a0c130f6f898cc6187e3b8964639f6c960bc9c08589dcac06506526","Cargo.toml":"6246515094dda94c71890606c39275b555aed886b5f4c789eb362ce7b1eea40f","LICENSE-APACHE":"d8621ec2eee5b9ca3c65f8492505f3590de8574fac0fdf5132a77232dba47abc","LICENSE-MIT":"30fefc3a7d6a0041541858293bcbea2dde4caa4c0a5802f996a7f7e8c0085652","README.md":"48f7ca4326cfcd3440931e5c82fc21f7b8a6f40041bc94be817c291ad71b6c5b","benches/basic.rs":"61ecb5f7c092b82382cc20e73ca84677dd4973cc358ea6bff15f92fda227b481","examples/async.rs":"7a0bb8848d94bd1fa9a857ffba0b3fbea6d57d7058ed65d2a7cbcf8518ec8652","examples/perf.rs":"52b67c619932a283ad9109c5fe5b47d32f7d3e7533356170047b686dfac330c9","examples/select.rs":"7659b015889545a59b9bce046fc353fea7bcaa9d54cb59f6bd5c002e15872909","examples/simple.rs":"f96d308b808b5fd66ca03dac9f09c13e5f13141992698551503415a411f6596a","src/async.rs":"851b0db2f8115eb222a9eb3c39d3dcdd8699c5b8e757580f26a03ca71c88d0e4","src/lib.rs":"36f84973b6bb45e54161dfb8eb574b30bace69d4b382e7fe8669d5636473d9ea","src/select.rs":"940cbdfbb26b9a2811bf42df3b26f1a619bd71896b8a6b6f2cdbb350c4fab270","src/signal.rs":"20a1732fdbfe888b9a25438bf16a185393f18fb1ad795926fae969c6817fe43b","tests/after.rs":"53e17263eab8eb733f575e4d1d43e054c6d22556d36e105f3f87c4cfb891880c","tests/array.rs":"2b071429d678e07ca52b79b4792120816a1ec7e64afd29c5781ddddbbbd7888b","tests/async.rs":"45bce43e990694578cf03c27dcf112df8d9ec1806e7c1be866885d76bb5abf85","tests/basic.rs":"0606408fe5ff1512839d43cc5c5f6a98c1e09fe919b5ad843643b5019926100b","tests/check_same_channel.rs":"e9e313d1ada50ac0ab0b9bcf19b901efd8cc226902edac62a8d573cea54e06ca","tests/golang.rs":"9e821cefd322a2353b288c7368902028daca643648da2e223ec1174c0e93e4ef","tests/iter.rs":"82d4f7acd20c9b10d2623211e71f5b6c37e4dafda2e13c871008c03995d76ced","tests/list.rs":"5885ee800d5c93b410d3bfa12d834fd817fd3362bca15a08b0aa7f84de58432e","tests/method_sharing.rs":"4d6c867e689254840ecbb1ae8a70ab3226d45bf92282e3bd2681c83726983ffa","tests/mpsc.rs":"965e18abbfcdebec09380f8ec9bb62e5556ad2aa0176ed088ce091994c1d2500","tests/never.rs":"cb838011c6f39c150c67e6836eb880300d53c22a2ea0312cdec999efb779ca29","tests/ready.rs":"5e1234ce49e8cbf89ec4f28bd2f4fe10641891bf6a7915d2fef6f9ab0c343997","tests/same_channel.rs":"71524e90dc364cc2c8085a9517757abe55f59a25b95600029abb283bc8677ad9","tests/select.rs":"67f8a647a7976f0d77673f4cc8d03b74690f3e8578c47e1bc64caeab68dd7df7","tests/select_macro.rs":"32793ac9775879e72ae3ce3975aa87f7407c6e7023d3d85f50f06a3ac5e308a3","tests/stream.rs":"c6d9500813d7216fd514f35dadb1b7b58282def553f40d76b37032221bb05cd6","tests/thread_locals.rs":"ad92e07a4ef5c3dd8b6ff8620161ab93963b3de241a680db551f2be60c8e3853","tests/tick.rs":"35fabd118073decf0cd830e9245c77a1a2e19227f7b4f73d239589728a591601","tests/zero.rs":"23a15a51681596716d5882242cd2c8cd0925c6ea2d0ef289f80775f3f2d6d10c"},"package":"55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181"}
\ No newline at end of file diff --git a/vendor/flume/CHANGELOG.md b/vendor/flume/CHANGELOG.md deleted file mode 100644 index 14a604f..0000000 --- a/vendor/flume/CHANGELOG.md +++ /dev/null @@ -1,134 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -# Unreleased - -### Added - -### Removed - -### Changed - -### Fixed - -# [0.11.0] - 2023-08-16 - -### Added - -- `WeakSender`, a sender that doesn't keep the channel open -- `Sender/Receiver::sender_count/receiver_count`, a way to query the number of senders and receivers attached to a channel -- `Sender/Receiver::same_channel`, a way to determine whether senders and receivers are attached to the same channel - -### Changed - -- Relaxed some API features -- Make all remaining spinlocks opt-in - -### Fixed - -- Fixed a rare race condition in the async implementation - -# [0.10.14] - 2022-07-21 - -### Fixed - -- Fixed unbounded memory usage in `RecvFut::poll_inner` - -# [0.10.13] - 2022-06-10 - -### Added - -- `SendSink::sender`, to get the sender of a `SendSink` - -# [0.10.12] - 2022-03-10 - -### Changed - -- Updated `nanorand` to 0.7 - -# [0.10.11] - 2022-02-14 - -### Fixed - -- Out-of-order bug when using channels asynchronously - -# [0.10.10] - 2022-01-11 - -### Added - -- `From<SendError>` and `From<RecvError>` impls for other error types -- Marked futures as `#[must_use]` - -### Changes - -- Switched to scheduler-driven locking by default, with a `spin` feature to reenable the old behaviour -- Minor doc improvements - -# [0.10.9] - 2021-08-25 - -### Changed - -- Switched from `spinning_top` to `spin` - -# [0.10.8] - 2021-08-06 - -### Changed - -- Updated `nanorand` to `0.6` - -# [0.10.7] - 2021-06-10 - -### Fixed - -- Removed accidental nightly-only syntax - -# [0.10.6] - 2021-06-10 - -### Added - -- `fn into_inner(self) -> T` for send errors, allowing for easy access to the unsent message - -# [0.10.5] - 2021-04-26 - -### Added - -- `is_disconnected`, `is_empty`, `is_full`, `len`, and `capacity` on future types - -# [0.10.4] - 2021-04-12 - -### Fixed - -- Shutdown-related race condition with async recv that caused spurious errors - -# [0.10.3] - 2021-04-09 - -### Fixed - -- Compilation error when enabling `select` without `eventual_fairness` - -# [0.10.2] - 2021-02-07 - -### Fixed - -- Incorrect pointer comparison in `Selector` causing missing receives - -# [0.10.1] - 2020-12-30 - -### Removed - -- Removed `T: Unpin` requirement from async traits using `pin_project` - -# [0.10.0] - 2020-12-09 - -### Changed - -- Renamed `SendFuture` to `SendFut` to be consistent with `RecvFut` -- Improved async-related documentation - -### Fixed - -- Updated `nanorand` to address security advisory diff --git a/vendor/flume/Cargo.lock b/vendor/flume/Cargo.lock deleted file mode 100644 index 43921dd..0000000 --- a/vendor/flume/Cargo.lock +++ /dev/null @@ -1,1312 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "addr2line" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "aho-corasick" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a" -dependencies = [ - "memchr", -] - -[[package]] -name = "async-attributes" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" -dependencies = [ - "quote", - "syn 1.0.109", -] - -[[package]] -name = "async-channel" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" -dependencies = [ - "concurrent-queue", - "event-listener", - "futures-core", -] - -[[package]] -name = "async-executor" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fa3dc5f2a8564f07759c008b9109dc0d39de92a88d5588b8a5036d286383afb" -dependencies = [ - "async-lock", - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "slab", -] - -[[package]] -name = "async-global-executor" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776" -dependencies = [ - "async-channel", - "async-executor", - "async-io", - "async-lock", - "blocking", - "futures-lite", - "once_cell", -] - -[[package]] -name = "async-io" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" -dependencies = [ - "async-lock", - "autocfg", - "cfg-if", - "concurrent-queue", - "futures-lite", - "log", - "parking", - "polling", - "rustix", - "slab", - "socket2", - "waker-fn", -] - -[[package]] -name = "async-lock" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" -dependencies = [ - "event-listener", -] - -[[package]] -name = "async-process" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a9d28b1d97e08915212e2e45310d47854eafa69600756fc735fb788f75199c9" -dependencies = [ - "async-io", - "async-lock", - "autocfg", - "blocking", - "cfg-if", - "event-listener", - "futures-lite", - "rustix", - "signal-hook", - "windows-sys", -] - -[[package]] -name = "async-std" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" -dependencies = [ - "async-attributes", - "async-channel", - "async-global-executor", - "async-io", - "async-lock", - "async-process", - "crossbeam-utils", - "futures-channel", - "futures-core", - "futures-io", - "futures-lite", - "gloo-timers", - "kv-log-macro", - "log", - "memchr", - "once_cell", - "pin-project-lite", - "pin-utils", - "slab", - "wasm-bindgen-futures", -] - -[[package]] -name = "async-task" -version = "4.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" - -[[package]] -name = "atomic-waker" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "backtrace" -version = "0.3.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "blocking" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77231a1c8f801696fc0123ec6150ce92cffb8e164a02afb9c8ddee0e9b65ad65" -dependencies = [ - "async-channel", - "async-lock", - "async-task", - "atomic-waker", - "fastrand", - "futures-lite", - "log", -] - -[[package]] -name = "bumpalo" -version = "3.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" - -[[package]] -name = "cast" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" - -[[package]] -name = "cc" -version = "1.0.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01" -dependencies = [ - "libc", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "clap" -version = "2.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" -dependencies = [ - "bitflags", - "textwrap", - "unicode-width", -] - -[[package]] -name = "concurrent-queue" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "criterion" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" -dependencies = [ - "atty", - "cast", - "clap", - "criterion-plot", - "csv", - "itertools", - "lazy_static", - "num-traits", - "oorandom", - "plotters", - "rayon", - "regex", - "serde", - "serde_cbor", - "serde_derive", - "serde_json", - "tinytemplate", - "walkdir", -] - -[[package]] -name = "criterion-plot" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876" -dependencies = [ - "cast", - "itertools", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "csv" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "626ae34994d3d8d668f4269922248239db4ae42d538b14c398b74a52208e8086" -dependencies = [ - "csv-core", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "csv-core" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" -dependencies = [ - "memchr", -] - -[[package]] -name = "either" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" - -[[package]] -name = "errno" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "event-listener" -version = "2.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" - -[[package]] -name = "fastrand" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] - -[[package]] -name = "flume" -version = "0.11.0" -dependencies = [ - "async-std", - "criterion", - "crossbeam-channel", - "crossbeam-utils", - "futures", - "futures-core", - "futures-sink", - "nanorand", - "rand", - "spin", - "tokio", - "waker-fn", -] - -[[package]] -name = "futures" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" - -[[package]] -name = "futures-executor" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" - -[[package]] -name = "futures-lite" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] - -[[package]] -name = "futures-macro" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.28", -] - -[[package]] -name = "futures-sink" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" - -[[package]] -name = "futures-task" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" - -[[package]] -name = "futures-util" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "getrandom" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", -] - -[[package]] -name = "gimli" -version = "0.27.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" - -[[package]] -name = "gloo-timers" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "half" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi 0.3.2", - "libc", - "windows-sys", -] - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" - -[[package]] -name = "js-sys" -version = "0.3.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "kv-log-macro" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" -dependencies = [ - "log", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.147" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" - -[[package]] -name = "linux-raw-sys" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" - -[[package]] -name = "lock_api" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" -dependencies = [ - "value-bag", -] - -[[package]] -name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - -[[package]] -name = "miniz_oxide" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" -dependencies = [ - "adler", -] - -[[package]] -name = "nanorand" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" -dependencies = [ - "getrandom", -] - -[[package]] -name = "num-traits" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi 0.3.2", - "libc", -] - -[[package]] -name = "object" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - -[[package]] -name = "oorandom" -version = "11.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" - -[[package]] -name = "parking" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" - -[[package]] -name = "pin-project-lite" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "plotters" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" -dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" - -[[package]] -name = "plotters-svg" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" -dependencies = [ - "plotters-backend", -] - -[[package]] -name = "polling" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" -dependencies = [ - "autocfg", - "bitflags", - "cfg-if", - "concurrent-queue", - "libc", - "log", - "pin-project-lite", - "windows-sys", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "proc-macro2" -version = "1.0.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rayon" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - -[[package]] -name = "regex" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" - -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - -[[package]] -name = "rustix" -version = "0.37.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" -dependencies = [ - "bitflags", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys", - "windows-sys", -] - -[[package]] -name = "ryu" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "serde" -version = "1.0.183" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" - -[[package]] -name = "serde_cbor" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" -dependencies = [ - "half", - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.183" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.28", -] - -[[package]] -name = "serde_json" -version = "1.0.105" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "signal-hook" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" -dependencies = [ - "libc", - "signal-hook-registry", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" -dependencies = [ - "libc", -] - -[[package]] -name = "slab" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" -dependencies = [ - "autocfg", -] - -[[package]] -name = "socket2" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "tinytemplate" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" -dependencies = [ - "serde", - "serde_json", -] - -[[package]] -name = "tokio" -version = "1.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40de3a2ba249dcb097e01be5e67a5ff53cf250397715a071a81543e8a832a920" -dependencies = [ - "backtrace", - "pin-project-lite", - "tokio-macros", -] - -[[package]] -name = "tokio-macros" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.28", -] - -[[package]] -name = "unicode-ident" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" - -[[package]] -name = "unicode-width" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" - -[[package]] -name = "value-bag" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d92ccd67fb88503048c01b59152a04effd0782d035a83a6d256ce6085f08f4a3" - -[[package]] -name = "waker-fn" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" - -[[package]] -name = "walkdir" -version = "2.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.28", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.28", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" - -[[package]] -name = "web-sys" -version = "0.3.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.48.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1eeca1c172a285ee6c2c84c341ccea837e7c01b12fbb2d0fe3c9e550ce49ec8" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b10d0c968ba7f6166195e13d593af609ec2e3d24f916f081690695cf5eaffb2f" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "571d8d4e62f26d4932099a9efe89660e8bd5087775a2ab5cdd8b747b811f1058" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2229ad223e178db5fbbc8bd8d3835e51e566b8474bfca58d2e6150c48bb723cd" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "600956e2d840c194eedfc5d18f8242bc2e17c7775b6684488af3a9fff6fe3287" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea99ff3f8b49fb7a8e0d305e5aec485bd068c2ba691b6e277d29eaeac945868a" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1a05a1ece9a7a0d5a7ccf30ba2c33e3a61a30e042ffd247567d1de1d94120d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d419259aba16b663966e29e6d7c6ecfa0bb8425818bb96f6f1f3c3eb71a6e7b9" diff --git a/vendor/flume/Cargo.toml b/vendor/flume/Cargo.toml deleted file mode 100644 index 4b4eca4..0000000 --- a/vendor/flume/Cargo.toml +++ /dev/null @@ -1,110 +0,0 @@ -# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO -# -# When uploading crates to the registry Cargo will automatically -# "normalize" Cargo.toml files for maximal compatibility -# with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies. -# -# If you are reading this file be aware that the original Cargo.toml -# will likely look very different (and much more reasonable). -# See Cargo.toml.orig for the original contents. - -[package] -edition = "2018" -name = "flume" -version = "0.11.0" -authors = ["Joshua Barretto <joshua.s.barretto@gmail.com>"] -exclude = [ - "/.github", - "/misc", -] -description = "A blazingly fast multi-producer channel" -documentation = "https://docs.rs/flume" -readme = "README.md" -keywords = [ - "mpsc", - "fifo", - "channel", - "thread", - "mpmc", -] -categories = [ - "concurrency", - "data-structures", -] -license = "Apache-2.0/MIT" -repository = "https://github.com/zesterer/flume" - -[[bench]] -name = "basic" -harness = false - -[dependencies.futures-core] -version = "0.3" -optional = true -default_features = false - -[dependencies.futures-sink] -version = "0.3" -optional = true -default_features = false - -[dependencies.nanorand] -version = "0.7" -features = ["getrandom"] -optional = true - -[dependencies.spin1] -version = "0.9.8" -features = ["mutex"] -package = "spin" - -[dev-dependencies.async-std] -version = "1.9.0" -features = [ - "attributes", - "unstable", -] - -[dev-dependencies.criterion] -version = "0.3.4" - -[dev-dependencies.crossbeam-channel] -version = "0.5.5" - -[dev-dependencies.crossbeam-utils] -version = "0.8.10" - -[dev-dependencies.futures] -version = "^0.3" -features = ["std"] - -[dev-dependencies.rand] -version = "0.8.3" - -[dev-dependencies.tokio] -version = "^1.16.1" -features = [ - "rt", - "macros", -] - -[dev-dependencies.waker-fn] -version = "1.1.0" - -[features] -async = [ - "futures-sink", - "futures-core", -] -default = [ - "async", - "select", - "eventual-fairness", -] -eventual-fairness = [ - "select", - "nanorand", -] -select = [] -spin = [] diff --git a/vendor/flume/LICENSE-APACHE b/vendor/flume/LICENSE-APACHE deleted file mode 100644 index f474855..0000000 --- a/vendor/flume/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License.
\ No newline at end of file diff --git a/vendor/flume/LICENSE-MIT b/vendor/flume/LICENSE-MIT deleted file mode 100644 index 468cd79..0000000 --- a/vendor/flume/LICENSE-MIT +++ /dev/null @@ -1,23 +0,0 @@ -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE.
\ No newline at end of file diff --git a/vendor/flume/README.md b/vendor/flume/README.md deleted file mode 100644 index d61155d..0000000 --- a/vendor/flume/README.md +++ /dev/null @@ -1,86 +0,0 @@ -# Flume - -A blazingly fast multi-producer, multi-consumer channel. - -[![Cargo](https://img.shields.io/crates/v/flume.svg)]( -https://crates.io/crates/flume) -[![Documentation](https://docs.rs/flume/badge.svg)]( -https://docs.rs/flume) -[![License](https://img.shields.io/badge/license-MIT%2FApache--2.0-blue.svg)]( -https://github.com/zesterer/flume) -![actions-badge](https://github.com/zesterer/flume/workflows/Rust/badge.svg?branch=master) - -```rust -use std::thread; - -fn main() { - println!("Hello, world!"); - - let (tx, rx) = flume::unbounded(); - - thread::spawn(move || { - (0..10).for_each(|i| { - tx.send(i).unwrap(); - }) - }); - - let received: u32 = rx.iter().sum(); - - assert_eq!((0..10).sum::<u32>(), received); -} -``` - -## Why Flume? - -- **Featureful**: Unbounded, bounded and rendezvous queues -- **Fast**: Always faster than `std::sync::mpsc` and sometimes `crossbeam-channel` -- **Safe**: No `unsafe` code anywhere in the codebase! -- **Flexible**: `Sender` and `Receiver` both implement `Send + Sync + Clone` -- **Familiar**: Drop-in replacement for `std::sync::mpsc` -- **Capable**: Additional features like MPMC support and send timeouts/deadlines -- **Simple**: Few dependencies, minimal codebase, fast to compile -- **Asynchronous**: `async` support, including mix 'n match with sync code -- **Ergonomic**: Powerful `select`-like interface - -## Usage - -To use Flume, place the following line under the `[dependencies]` section in your `Cargo.toml`: - -```toml -flume = "x.y" -``` - -## Cargo Features - -Flume comes with several optional features: - -- `spin`: use spinlocks instead of OS-level synchronisation primitives internally for some kind of data access (may be more performant on a small number of platforms for specific workloads) - -- `select`: Adds support for the [`Selector`](https://docs.rs/flume/latest/flume/select/struct.Selector.html) API, allowing a thread to wait on several channels/operations at once - -- `async`: Adds support for the [async API](https://docs.rs/flume/latest/flume/async/index.html), including on otherwise synchronous channels - -- `eventual-fairness`: Use randomness in the implementation of `Selector` to avoid biasing/saturating certain events over others - -You can enable these features by changing the dependency in your `Cargo.toml` like so: - -```toml -flume = { version = "x.y", default-features = false, features = ["async", "select"] } -``` - -## [Benchmarks](https://what-if.xkcd.com/147/) - -Although Flume has its own extensive benchmarks, don't take it from here that Flume is quick. -The following graph is from the `crossbeam-channel` benchmark suite. - -Tests were performed on an AMD Ryzen 7 3700x with 8/16 cores running Linux kernel 5.11.2 with the bfq scheduler. - -# <img src="misc/benchmarks.png" alt="Flume benchmarks (crossbeam benchmark suite)" width="100%"/> - -## License - -Flume is licensed under either of: - -- Apache License 2.0, (http://www.apache.org/licenses/LICENSE-2.0) - -- MIT license (http://opensource.org/licenses/MIT) diff --git a/vendor/flume/benches/basic.rs b/vendor/flume/benches/basic.rs deleted file mode 100644 index bbc4fc2..0000000 --- a/vendor/flume/benches/basic.rs +++ /dev/null @@ -1,474 +0,0 @@ -#[macro_use] -extern crate criterion; - -use std::{ - sync::mpsc, - thread, - fmt::Debug, -}; -use criterion::{Criterion, Bencher, black_box}; -use std::time::Instant; - -trait Sender: Clone + Send + Sized + 'static { - type Item: Debug + Default; - type BoundedSender: Sender<Item=Self::Item>; - type Receiver: Receiver<Item=Self::Item>; - - fn unbounded() -> (Self, Self::Receiver); - fn bounded(n: usize) -> (Self::BoundedSender, Self::Receiver); - fn send(&self, msg: Self::Item); -} - -trait Receiver: Send + Sized + 'static { - type Item: Default; - fn recv(&self) -> Self::Item; - fn iter(&self) -> Box<dyn Iterator<Item=Self::Item> + '_>; -} - -impl<T: Send + Debug + Default + 'static> Sender for flume::Sender<T> { - type Item = T; - type BoundedSender = Self; - type Receiver = flume::Receiver<T>; - - fn unbounded() -> (Self, Self::Receiver) { - flume::unbounded() - } - - fn bounded(n: usize) -> (Self::BoundedSender, Self::Receiver) { - flume::bounded(n) - } - - fn send(&self, msg: T) { - flume::Sender::send(self, msg).unwrap(); - } -} - -impl<T: Send + Default + 'static> Receiver for flume::Receiver<T> { - type Item = T; - - fn recv(&self) -> Self::Item { - flume::Receiver::recv(self).unwrap() - } - - fn iter(&self) -> Box<dyn Iterator<Item=T> + '_> { - Box::new(std::iter::from_fn(move || flume::Receiver::recv(self).ok())) - } -} - -impl<T: Send + Debug + Default + 'static> Sender for crossbeam_channel::Sender<T> { - type Item = T; - type BoundedSender = Self; - type Receiver = crossbeam_channel::Receiver<T>; - - fn unbounded() -> (Self, Self::Receiver) { - crossbeam_channel::unbounded() - } - - fn bounded(n: usize) -> (Self::BoundedSender, Self::Receiver) { - crossbeam_channel::bounded(n) - } - - fn send(&self, msg: T) { - crossbeam_channel::Sender::send(self, msg).unwrap(); - } -} - -impl<T: Send + Default + 'static> Receiver for crossbeam_channel::Receiver<T> { - type Item = T; - - fn recv(&self) -> Self::Item { - crossbeam_channel::Receiver::recv(self).unwrap() - } - - fn iter(&self) -> Box<dyn Iterator<Item=T> + '_> { - Box::new(crossbeam_channel::Receiver::iter(self)) - } -} - -impl<T: Send + Debug + Default + 'static> Sender for mpsc::Sender<T> { - type Item = T; - type BoundedSender = mpsc::SyncSender<T>; - type Receiver = mpsc::Receiver<T>; - - fn unbounded() -> (Self, Self::Receiver) { - mpsc::channel() - } - - fn bounded(n: usize) -> (Self::BoundedSender, Self::Receiver) { - mpsc::sync_channel(n) - } - - fn send(&self, msg: T) { - mpsc::Sender::send(self, msg).unwrap(); - } -} - -impl<T: Send + Debug + Default + 'static> Sender for mpsc::SyncSender<T> { - type Item = T; - type BoundedSender = Self; - type Receiver = mpsc::Receiver<T>; - - fn unbounded() -> (Self, Self::Receiver) { unimplemented!() } - fn bounded(_: usize) -> (Self::BoundedSender, Self::Receiver) { unimplemented!() } - - fn send(&self, msg: T) { - mpsc::SyncSender::send(self, msg).unwrap(); - } -} - -impl<T: Send + Default + 'static> Receiver for mpsc::Receiver<T> { - type Item = T; - - fn recv(&self) -> Self::Item { - mpsc::Receiver::recv(self).unwrap() - } - - fn iter(&self) -> Box<dyn Iterator<Item=T> + '_> { - Box::new(mpsc::Receiver::iter(self)) - } -} - -fn test_create<S: Sender>(b: &mut Bencher) { - b.iter(|| S::unbounded()); -} - -fn test_oneshot<S: Sender>(b: &mut Bencher) { - b.iter(|| { - let (tx, rx) = S::unbounded(); - tx.send(Default::default()); - black_box(rx.recv()); - }); -} - -fn test_inout<S: Sender>(b: &mut Bencher) { - let (tx, rx) = S::unbounded(); - b.iter(|| { - tx.send(Default::default()); - black_box(rx.recv()); - }); -} - -fn test_hydra<S: Sender>(b: &mut Bencher, thread_num: usize, msg_num: usize) { - let (main_tx, main_rx) = S::unbounded(); - - let mut txs = Vec::new(); - for _ in 0..thread_num { - let main_tx = main_tx.clone(); - let (tx, rx) = S::unbounded(); - txs.push(tx); - - thread::spawn(move || { - for msg in rx.iter() { - main_tx.send(msg); - } - }); - } - - drop(main_tx); - - b.iter(|| { - for tx in &txs { - for _ in 0..msg_num { - tx.send(Default::default()); - } - } - - for _ in 0..thread_num { - for _ in 0..msg_num { - black_box(main_rx.recv()); - } - } - }); -} - -fn test_kitsune<S: Sender>(b: &mut Bencher, thread_num: usize, msg_num: usize) - where S::Receiver: Clone -{ - let (out_tx, out_rx) = S::unbounded(); - let (in_tx, in_rx) = S::unbounded(); - - for _ in 0..thread_num { - let in_tx = in_tx.clone(); - let out_rx = out_rx.clone(); - - thread::spawn(move || { - for msg in out_rx.iter() { - in_tx.send(msg); - } - }); - } - - b.iter(|| { - for _ in 0..thread_num { - for _ in 0..msg_num { - out_tx.send(Default::default()); - } - } - - for _ in 0..thread_num { - for _ in 0..msg_num { - black_box(in_rx.recv()); - } - } - }); -} - -fn test_robin_u<S: Sender>(b: &mut Bencher, thread_num: usize, msg_num: usize) { - let (mut main_tx, main_rx) = S::unbounded(); - - for _ in 0..thread_num { - let (mut tx, rx) = S::unbounded(); - std::mem::swap(&mut tx, &mut main_tx); - - thread::spawn(move || { - for msg in rx.iter() { - tx.send(msg); - } - }); - } - - b.iter(|| { - for _ in 0..msg_num { - main_tx.send(Default::default()); - } - - for _ in 0..msg_num { - black_box(main_rx.recv()); - } - }); -} - -fn test_robin_b<S: Sender>(b: &mut Bencher, thread_num: usize, msg_num: usize) { - let (mut main_tx, main_rx) = S::bounded(1); - - for _ in 0..thread_num { - let (mut tx, rx) = S::bounded(1); - std::mem::swap(&mut tx, &mut main_tx); - - thread::spawn(move || { - for msg in rx.iter() { - tx.send(msg); - } - }); - } - - b.iter(|| { - let main_tx = main_tx.clone(); - thread::spawn(move || { - for _ in 0..msg_num { - main_tx.send(Default::default()); - } - }); - - for _ in 0..msg_num { - black_box(main_rx.recv()); - } - }); -} - -fn test_mpsc_bounded_no_wait<S: Sender>(b: &mut Bencher, thread_num: u64) { - b.iter_custom(|iters| { - let iters = iters * 1000; - let (tx, rx) = S::bounded(iters as usize); - let start = Instant::now(); - - crossbeam_utils::thread::scope(|scope| { - for _ in 0..thread_num { - let tx = tx.clone(); - scope.spawn(move |_| { - for _ in 0..iters / thread_num { - tx.send(Default::default()); - } - }); - } - - for _ in 0..iters - ((iters / thread_num) * thread_num) { - tx.send(Default::default()); - } - - for _ in 0..iters { - black_box(rx.recv()); - } - }) - .unwrap(); - - start.elapsed() - }) -} - -fn test_mpsc_bounded<S: Sender>(b: &mut Bencher, bound: usize, thread_num: usize) { - b.iter_custom(|iters| { - let (tx, rx) = S::bounded(bound); - let start = Instant::now(); - - crossbeam_utils::thread::scope(|scope| { - let msgs = iters as usize * bound.max(1); - - for _ in 0..thread_num { - let tx = tx.clone(); - scope.spawn(move |_| { - for _ in 0..msgs / thread_num as usize { - tx.send(Default::default()); - } - }); - } - - scope.spawn(move |_| { - // Remainder - for _ in 0..msgs - (msgs / thread_num as usize * thread_num) { - tx.send(Default::default()); - } - }); - - for _ in 0..msgs { - black_box(rx.recv()); - } - }) - .unwrap(); - - start.elapsed() - }) -} - -fn create(b: &mut Criterion) { - b.bench_function("create-flume", |b| test_create::<flume::Sender<u32>>(b)); - b.bench_function("create-crossbeam", |b| test_create::<crossbeam_channel::Sender<u32>>(b)); - b.bench_function("create-std", |b| test_create::<mpsc::Sender<u32>>(b)); -} - -fn oneshot(b: &mut Criterion) { - b.bench_function("oneshot-flume", |b| test_oneshot::<flume::Sender<u32>>(b)); - b.bench_function("oneshot-crossbeam", |b| test_oneshot::<crossbeam_channel::Sender<u32>>(b)); - b.bench_function("oneshot-std", |b| test_oneshot::<mpsc::Sender<u32>>(b)); -} - -fn inout(b: &mut Criterion) { - b.bench_function("inout-flume", |b| test_inout::<flume::Sender<u32>>(b)); - b.bench_function("inout-crossbeam", |b| test_inout::<crossbeam_channel::Sender<u32>>(b)); - b.bench_function("inout-std", |b| test_inout::<mpsc::Sender<u32>>(b)); -} - -fn hydra_32t_1m(b: &mut Criterion) { - b.bench_function("hydra-32t-1m-flume", |b| test_hydra::<flume::Sender<u32>>(b, 32, 1)); - b.bench_function("hydra-32t-1m-crossbeam", |b| test_hydra::<crossbeam_channel::Sender<u32>>(b, 32, 1)); - b.bench_function("hydra-32t-1m-std", |b| test_hydra::<mpsc::Sender<u32>>(b, 32, 1)); -} - -fn hydra_32t_1000m(b: &mut Criterion) { - b.bench_function("hydra-32t-1000m-flume", |b| test_hydra::<flume::Sender<u32>>(b, 32, 1000)); - b.bench_function("hydra-32t-1000m-crossbeam", |b| test_hydra::<crossbeam_channel::Sender<u32>>(b, 32, 1000)); - b.bench_function("hydra-32t-1000m-std", |b| test_hydra::<mpsc::Sender<u32>>(b, 32, 1000)); -} - -fn hydra_256t_1m(b: &mut Criterion) { - b.bench_function("hydra-256t-1m-flume", |b| test_hydra::<flume::Sender<u32>>(b, 256, 1)); - b.bench_function("hydra-256t-1m-crossbeam", |b| test_hydra::<crossbeam_channel::Sender<u32>>(b, 256, 1)); - b.bench_function("hydra-256t-1m-std", |b| test_hydra::<mpsc::Sender<u32>>(b, 256, 1)); -} - -fn hydra_1t_1000m(b: &mut Criterion) { - b.bench_function("hydra-1t-1000m-flume", |b| test_hydra::<flume::Sender<u32>>(b, 1, 1000)); - b.bench_function("hydra-1t-1000m-crossbeam", |b| test_hydra::<crossbeam_channel::Sender<u32>>(b, 1, 1000)); - b.bench_function("hydra-1t-1000m-std", |b| test_hydra::<mpsc::Sender<u32>>(b, 1, 1000)); -} - -fn hydra_4t_10000m(b: &mut Criterion) { - b.bench_function("hydra-4t-10000m-flume", |b| test_hydra::<flume::Sender<u32>>(b, 4, 10000)); - b.bench_function("hydra-4t-10000m-crossbeam", |b| test_hydra::<crossbeam_channel::Sender<u32>>(b, 4, 10000)); - b.bench_function("hydra-4t-10000m-std", |b| test_hydra::<mpsc::Sender<u32>>(b, 4, 10000)); -} - -fn kitsune_32t_1m(b: &mut Criterion) { - b.bench_function("kitsune-32t-1m-flume", |b| test_kitsune::<flume::Sender<u32>>(b, 32, 1)); - b.bench_function("kitsune-32t-1m-crossbeam", |b| test_kitsune::<crossbeam_channel::Sender<u32>>(b, 32, 1)); - //b.bench_function("kitsune-32t-1m-std", |b| test_kitsune::<mpsc::Sender<u32>>(b, 32, 1)); -} - -fn kitsune_32t_1000m(b: &mut Criterion) { - b.bench_function("kitsune-32t-1000m-flume", |b| test_kitsune::<flume::Sender<u32>>(b, 32, 1000)); - b.bench_function("kitsune-32t-1000m-crossbeam", |b| test_kitsune::<crossbeam_channel::Sender<u32>>(b, 32, 1000)); - //b.bench_function("kitsune-32t-1000m-std", |b| test_kitsune::<mpsc::Sender<u32>>(b, 32, 1000)); -} - -fn kitsune_256t_1m(b: &mut Criterion) { - b.bench_function("kitsune-256t-1m-flume", |b| test_kitsune::<flume::Sender<u32>>(b, 256, 1)); - b.bench_function("kitsune-256t-1m-crossbeam", |b| test_kitsune::<crossbeam_channel::Sender<u32>>(b, 256, 1)); - //b.bench_function("kitsune-256t-1m-std", |b| test_kitsune::<mpsc::Sender<u32>>(b, 256, 1)); -} - -fn kitsune_1t_1000m(b: &mut Criterion) { - b.bench_function("kitsune-1t-1000m-flume", |b| test_kitsune::<flume::Sender<u32>>(b, 1, 1000)); - b.bench_function("kitsune-1t-1000m-crossbeam", |b| test_kitsune::<crossbeam_channel::Sender<u32>>(b, 1, 1000)); - //b.bench_function("kitsune-1t-1000m-std", |b| test_kitsune::<mpsc::Sender<u32>>(b, 1, 1000)); -} - -fn kitsune_4t_10000m(b: &mut Criterion) { - b.bench_function("kitsune-4t-10000m-flume", |b| test_kitsune::<flume::Sender<u32>>(b, 4, 10000)); - b.bench_function("kitsune-4t-10000m-crossbeam", |b| test_kitsune::<crossbeam_channel::Sender<u32>>(b, 4, 10000)); - //b.bench_function("kitsune-4t-10000m-std", |b| test_kitsune::<mpsc::Sender<u32>>(b, 4, 10000)); -} - -fn robin_u_32t_1m(b: &mut Criterion) { - b.bench_function("robin-u-32t-1m-flume", |b| test_robin_u::<flume::Sender<u32>>(b, 32, 1)); - b.bench_function("robin-u-32t-1m-crossbeam", |b| test_robin_u::<crossbeam_channel::Sender<u32>>(b, 32, 1)); - b.bench_function("robin-u-32t-1m-std", |b| test_robin_u::<mpsc::Sender<u32>>(b, 32, 1)); -} - -fn robin_u_4t_1000m(b: &mut Criterion) { - b.bench_function("robin-u-4t-1000m-flume", |b| test_robin_u::<flume::Sender<u32>>(b, 4, 1000)); - b.bench_function("robin-u-4t-1000m-crossbeam", |b| test_robin_u::<crossbeam_channel::Sender<u32>>(b, 4, 1000)); - b.bench_function("robin-u-4t-1000m-std", |b| test_robin_u::<mpsc::Sender<u32>>(b, 4, 1000)); -} - -fn robin_b_32t_16m(b: &mut Criterion) { - b.bench_function("robin-b-32t-16m-flume", |b| test_robin_b::<flume::Sender<u32>>(b, 32, 16)); - b.bench_function("robin-b-32t-16m-crossbeam", |b| test_robin_b::<crossbeam_channel::Sender<u32>>(b, 32, 16)); - b.bench_function("robin-b-32t-16m-std", |b| test_robin_b::<mpsc::Sender<u32>>(b, 32, 16)); -} - -fn robin_b_4t_1000m(b: &mut Criterion) { - b.bench_function("robin-b-4t-1000m-flume", |b| test_robin_b::<flume::Sender<u32>>(b, 4, 1000)); - b.bench_function("robin-b-4t-1000m-crossbeam", |b| test_robin_b::<crossbeam_channel::Sender<u32>>(b, 4, 1000)); - b.bench_function("robin-b-4t-1000m-std", |b| test_robin_b::<mpsc::Sender<u32>>(b, 4, 1000)); -} - -fn mpsc_bounded_no_wait_4t(b: &mut Criterion) { - b.bench_function("mpsc-bounded-no-wait-4t-flume", |b| test_mpsc_bounded_no_wait::<flume::Sender<u32>>(b, 4)); - b.bench_function("mpsc-bounded-no-wait-4t-crossbeam", |b| test_mpsc_bounded_no_wait::<crossbeam_channel::Sender<u32>>(b, 4)); - b.bench_function("mpsc-bounded-no-wait-4t-std", |b| test_mpsc_bounded_no_wait::<mpsc::Sender<u32>>(b, 4)); -} - -fn mpsc_bounded_4t(b: &mut Criterion) { - for bound in &[0, 1, 10, 50, 10_000] { - let text = format!("mpsc-bounded-small-4t-{}m-", bound); - let bound = *bound; - - b.bench_function(&format!("{}{}", text, "flume"), |b| test_mpsc_bounded::<flume::Sender<u32>>(b, bound, 4)); - b.bench_function(&format!("{}{}", text, "crossbeam"), |b| test_mpsc_bounded::<crossbeam_channel::Sender<u32>>(b, bound, 4)); - b.bench_function(&format!("{}{}", text, "std"), |b| test_mpsc_bounded::<mpsc::Sender<u32>>(b, bound, 4)); - } -} - -criterion_group!( - compare, - create, - oneshot, - inout, - hydra_32t_1m, - hydra_32t_1000m, - hydra_256t_1m, - hydra_1t_1000m, - hydra_4t_10000m, - robin_b_32t_16m, - robin_b_4t_1000m, - robin_u_32t_1m, - robin_u_4t_1000m, - mpsc_bounded_no_wait_4t, - mpsc_bounded_4t, - kitsune_32t_1m, - kitsune_32t_1000m, - kitsune_256t_1m, - kitsune_1t_1000m, - kitsune_4t_10000m, -); -criterion_main!(compare); diff --git a/vendor/flume/examples/async.rs b/vendor/flume/examples/async.rs deleted file mode 100644 index a562700..0000000 --- a/vendor/flume/examples/async.rs +++ /dev/null @@ -1,21 +0,0 @@ -#[cfg(feature = "async")] -#[async_std::main] -async fn main() { - let (tx, rx) = flume::bounded(1); - - let t = async_std::task::spawn(async move { - while let Ok(msg) = rx.recv_async().await { - println!("Received: {}", msg); - } - }); - - tx.send_async("Hello, world!").await.unwrap(); - tx.send_async("How are you today?").await.unwrap(); - - drop(tx); - - t.await; -} - -#[cfg(not(feature = "async"))] -fn main() {} diff --git a/vendor/flume/examples/perf.rs b/vendor/flume/examples/perf.rs deleted file mode 100644 index 054dcbd..0000000 --- a/vendor/flume/examples/perf.rs +++ /dev/null @@ -1,30 +0,0 @@ -fn main() { - let thread_num = 32; - let msg_num = 16; - - let (mut main_tx, main_rx) = flume::bounded::<()>(1); - - for _ in 0..thread_num { - let (mut tx, rx) = flume::bounded(1); - std::mem::swap(&mut tx, &mut main_tx); - - std::thread::spawn(move || { - for msg in rx.iter() { - tx.send(msg).unwrap(); - } - }); - } - - for _ in 0..1000 { - let main_tx = main_tx.clone(); - std::thread::spawn(move || { - for _ in 0..msg_num { - main_tx.send(Default::default()).unwrap(); - } - }); - - for _ in 0..msg_num { - main_rx.recv().unwrap(); - } - } -} diff --git a/vendor/flume/examples/select.rs b/vendor/flume/examples/select.rs deleted file mode 100644 index bbe957b..0000000 --- a/vendor/flume/examples/select.rs +++ /dev/null @@ -1,25 +0,0 @@ -#[cfg(feature = "select")] -use flume::Selector; - -#[cfg(feature = "select")] -fn main() { - // Create two channels - let (red_tx, red_rx) = flume::unbounded(); - let (blue_tx, blue_rx) = flume::unbounded(); - - // Spawn two threads that each send a message into their respective channel - std::thread::spawn(move || { let _ = red_tx.send("Red"); }); - std::thread::spawn(move || { let _ = blue_tx.send("Blue"); }); - - // Race them to see which one sends their message first - let winner = Selector::new() - .recv(&red_rx, |msg| msg) - .recv(&blue_rx, |msg| msg) - .wait() - .unwrap(); - - println!("{} won!", winner); -} - -#[cfg(not(feature = "select"))] -fn main() {} diff --git a/vendor/flume/examples/simple.rs b/vendor/flume/examples/simple.rs deleted file mode 100644 index 39cb1bd..0000000 --- a/vendor/flume/examples/simple.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::thread; - -fn main() { - let (tx, rx) = flume::unbounded(); - - let t = thread::spawn(move || { - for msg in rx.iter() { - println!("Received: {}", msg); - } - }); - - tx.send("Hello, world!").unwrap(); - tx.send("How are you today?").unwrap(); - - drop(tx); - - t.join().unwrap(); -} diff --git a/vendor/flume/src/async.rs b/vendor/flume/src/async.rs deleted file mode 100644 index fae44d4..0000000 --- a/vendor/flume/src/async.rs +++ /dev/null @@ -1,543 +0,0 @@ -//! Futures and other types that allow asynchronous interaction with channels. - -use std::{ - future::Future, - pin::Pin, - task::{Context, Poll, Waker}, - any::Any, - ops::Deref, -}; -use crate::*; -use futures_core::{stream::{Stream, FusedStream}, future::FusedFuture}; -use futures_sink::Sink; -use spin1::Mutex as Spinlock; - -struct AsyncSignal { - waker: Spinlock<Waker>, - woken: AtomicBool, - stream: bool, -} - -impl AsyncSignal { - fn new(cx: &Context, stream: bool) -> Self { - AsyncSignal { - waker: Spinlock::new(cx.waker().clone()), - woken: AtomicBool::new(false), - stream, - } - } -} - -impl Signal for AsyncSignal { - fn fire(&self) -> bool { - self.woken.store(true, Ordering::SeqCst); - self.waker.lock().wake_by_ref(); - self.stream - } - - fn as_any(&self) -> &(dyn Any + 'static) { self } - fn as_ptr(&self) -> *const () { self as *const _ as *const () } -} - -impl<T> Hook<T, AsyncSignal> { - // Update the hook to point to the given Waker. - // Returns whether the hook has been previously awakened - fn update_waker(&self, cx_waker: &Waker) -> bool { - let mut waker = self.1.waker.lock(); - let woken = self.1.woken.load(Ordering::SeqCst); - if !waker.will_wake(cx_waker) { - *waker = cx_waker.clone(); - - // Avoid the edge case where the waker was woken just before the wakers were - // swapped. - if woken { - cx_waker.wake_by_ref(); - } - } - woken - } -} - -#[derive(Clone)] -enum OwnedOrRef<'a, T> { - Owned(T), - Ref(&'a T), -} - -impl<'a, T> Deref for OwnedOrRef<'a, T> { - type Target = T; - - fn deref(&self) -> &T { - match self { - OwnedOrRef::Owned(arc) => &arc, - OwnedOrRef::Ref(r) => r, - } - } -} - -impl<T> Sender<T> { - /// Asynchronously send a value into the channel, returning an error if all receivers have been - /// dropped. If the channel is bounded and is full, the returned future will yield to the async - /// runtime. - /// - /// In the current implementation, the returned future will not yield to the async runtime if the - /// channel is unbounded. This may change in later versions. - pub fn send_async(&self, item: T) -> SendFut<T> { - SendFut { - sender: OwnedOrRef::Ref(&self), - hook: Some(SendState::NotYetSent(item)), - } - } - - /// Convert this sender into a future that asynchronously sends a single message into the channel, - /// returning an error if all receivers have been dropped. If the channel is bounded and is full, - /// this future will yield to the async runtime. - /// - /// In the current implementation, the returned future will not yield to the async runtime if the - /// channel is unbounded. This may change in later versions. - pub fn into_send_async<'a>(self, item: T) -> SendFut<'a, T> { - SendFut { - sender: OwnedOrRef::Owned(self), - hook: Some(SendState::NotYetSent(item)), - } - } - - /// Create an asynchronous sink that uses this sender to asynchronously send messages into the - /// channel. The sender will continue to be usable after the sink has been dropped. - /// - /// In the current implementation, the returned sink will not yield to the async runtime if the - /// channel is unbounded. This may change in later versions. - pub fn sink(&self) -> SendSink<'_, T> { - SendSink(SendFut { - sender: OwnedOrRef::Ref(&self), - hook: None, - }) - } - - /// Convert this sender into a sink that allows asynchronously sending messages into the channel. - /// - /// In the current implementation, the returned sink will not yield to the async runtime if the - /// channel is unbounded. This may change in later versions. - pub fn into_sink<'a>(self) -> SendSink<'a, T> { - SendSink(SendFut { - sender: OwnedOrRef::Owned(self), - hook: None, - }) - } -} - -enum SendState<T> { - NotYetSent(T), - QueuedItem(Arc<Hook<T, AsyncSignal>>), -} - -/// A future that sends a value into a channel. -/// -/// Can be created via [`Sender::send_async`] or [`Sender::into_send_async`]. -#[must_use = "futures/streams/sinks do nothing unless you `.await` or poll them"] -pub struct SendFut<'a, T> { - sender: OwnedOrRef<'a, Sender<T>>, - // Only none after dropping - hook: Option<SendState<T>>, -} - -impl<T> std::marker::Unpin for SendFut<'_, T> {} - -impl<'a, T> SendFut<'a, T> { - /// Reset the hook, clearing it and removing it from the waiting sender's queue. This is called - /// on drop and just before `start_send` in the `Sink` implementation. - fn reset_hook(&mut self) { - if let Some(SendState::QueuedItem(hook)) = self.hook.take() { - let hook: Arc<Hook<T, dyn Signal>> = hook; - wait_lock(&self.sender.shared.chan).sending - .as_mut() - .unwrap().1 - .retain(|s| s.signal().as_ptr() != hook.signal().as_ptr()); - } - } - - /// See [`Sender::is_disconnected`]. - pub fn is_disconnected(&self) -> bool { - self.sender.is_disconnected() - } - - /// See [`Sender::is_empty`]. - pub fn is_empty(&self) -> bool { - self.sender.is_empty() - } - - /// See [`Sender::is_full`]. - pub fn is_full(&self) -> bool { - self.sender.is_full() - } - - /// See [`Sender::len`]. - pub fn len(&self) -> usize { - self.sender.len() - } - - /// See [`Sender::capacity`]. - pub fn capacity(&self) -> Option<usize> { - self.sender.capacity() - } -} - -impl<'a, T> Drop for SendFut<'a, T> { - fn drop(&mut self) { - self.reset_hook() - } -} - - -impl<'a, T> Future for SendFut<'a, T> { - type Output = Result<(), SendError<T>>; - - fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { - if let Some(SendState::QueuedItem(hook)) = self.hook.as_ref() { - if hook.is_empty() { - Poll::Ready(Ok(())) - } else if self.sender.shared.is_disconnected() { - let item = hook.try_take(); - self.hook = None; - match item { - Some(item) => Poll::Ready(Err(SendError(item))), - None => Poll::Ready(Ok(())), - } - } else { - hook.update_waker(cx.waker()); - Poll::Pending - } - } else if let Some(SendState::NotYetSent(item)) = self.hook.take() { - let this = self.get_mut(); - let (shared, this_hook) = (&this.sender.shared, &mut this.hook); - - shared.send( - // item - item, - // should_block - true, - // make_signal - |msg| Hook::slot(Some(msg), AsyncSignal::new(cx, false)), - // do_block - |hook| { - *this_hook = Some(SendState::QueuedItem(hook)); - Poll::Pending - }, - ) - .map(|r| r.map_err(|err| match err { - TrySendTimeoutError::Disconnected(msg) => SendError(msg), - _ => unreachable!(), - })) - } else { // Nothing to do - Poll::Ready(Ok(())) - } - } -} - -impl<'a, T> FusedFuture for SendFut<'a, T> { - fn is_terminated(&self) -> bool { - self.sender.shared.is_disconnected() - } -} - -/// A sink that allows sending values into a channel. -/// -/// Can be created via [`Sender::sink`] or [`Sender::into_sink`]. -pub struct SendSink<'a, T>(SendFut<'a, T>); - -impl<'a, T> SendSink<'a, T> { - /// Returns a clone of a sending half of the channel of this sink. - pub fn sender(&self) -> &Sender<T> { - &self.0.sender - } - - /// See [`Sender::is_disconnected`]. - pub fn is_disconnected(&self) -> bool { - self.0.is_disconnected() - } - - /// See [`Sender::is_empty`]. - pub fn is_empty(&self) -> bool { - self.0.is_empty() - } - - /// See [`Sender::is_full`]. - pub fn is_full(&self) -> bool { - self.0.is_full() - } - - /// See [`Sender::len`]. - pub fn len(&self) -> usize { - self.0.len() - } - - /// See [`Sender::capacity`]. - pub fn capacity(&self) -> Option<usize> { - self.0.capacity() - } - - /// Returns whether the SendSinks are belong to the same channel. - pub fn same_channel(&self, other: &Self) -> bool { - self.sender().same_channel(other.sender()) - } -} - -impl<'a, T> Sink<T> for SendSink<'a, T> { - type Error = SendError<T>; - - fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> { - Pin::new(&mut self.0).poll(cx) - } - - fn start_send(mut self: Pin<&mut Self>, item: T) -> Result<(), Self::Error> { - self.0.reset_hook(); - self.0.hook = Some(SendState::NotYetSent(item)); - - Ok(()) - } - - fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> { - Pin::new(&mut self.0).poll(cx) // TODO: A different strategy here? - } - - fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> { - Pin::new(&mut self.0).poll(cx) // TODO: A different strategy here? - } -} - -impl<'a, T> Clone for SendSink<'a, T> { - fn clone(&self) -> SendSink<'a, T> { - SendSink(SendFut { - sender: self.0.sender.clone(), - hook: None, - }) - } -} - -impl<T> Receiver<T> { - /// Asynchronously receive a value from the channel, returning an error if all senders have been - /// dropped. If the channel is empty, the returned future will yield to the async runtime. - pub fn recv_async(&self) -> RecvFut<'_, T> { - RecvFut::new(OwnedOrRef::Ref(self)) - } - - /// Convert this receiver into a future that asynchronously receives a single message from the - /// channel, returning an error if all senders have been dropped. If the channel is empty, this - /// future will yield to the async runtime. - pub fn into_recv_async<'a>(self) -> RecvFut<'a, T> { - RecvFut::new(OwnedOrRef::Owned(self)) - } - - /// Create an asynchronous stream that uses this receiver to asynchronously receive messages - /// from the channel. The receiver will continue to be usable after the stream has been dropped. - pub fn stream(&self) -> RecvStream<'_, T> { - RecvStream(RecvFut::new(OwnedOrRef::Ref(self))) - } - - /// Convert this receiver into a stream that allows asynchronously receiving messages from the channel. - pub fn into_stream<'a>(self) -> RecvStream<'a, T> { - RecvStream(RecvFut::new(OwnedOrRef::Owned(self))) - } -} - -/// A future which allows asynchronously receiving a message. -/// -/// Can be created via [`Receiver::recv_async`] or [`Receiver::into_recv_async`]. -#[must_use = "futures/streams/sinks do nothing unless you `.await` or poll them"] -pub struct RecvFut<'a, T> { - receiver: OwnedOrRef<'a, Receiver<T>>, - hook: Option<Arc<Hook<T, AsyncSignal>>>, -} - -impl<'a, T> RecvFut<'a, T> { - fn new(receiver: OwnedOrRef<'a, Receiver<T>>) -> Self { - Self { - receiver, - hook: None, - } - } - - /// Reset the hook, clearing it and removing it from the waiting receivers queue and waking - /// another receiver if this receiver has been woken, so as not to cause any missed wakeups. - /// This is called on drop and after a new item is received in `Stream::poll_next`. - fn reset_hook(&mut self) { - if let Some(hook) = self.hook.take() { - let hook: Arc<Hook<T, dyn Signal>> = hook; - let mut chan = wait_lock(&self.receiver.shared.chan); - // We'd like to use `Arc::ptr_eq` here but it doesn't seem to work consistently with wide pointers? - chan.waiting.retain(|s| s.signal().as_ptr() != hook.signal().as_ptr()); - if hook.signal().as_any().downcast_ref::<AsyncSignal>().unwrap().woken.load(Ordering::SeqCst) { - // If this signal has been fired, but we're being dropped (and so not listening to it), - // pass the signal on to another receiver - chan.try_wake_receiver_if_pending(); - } - } - } - - fn poll_inner( - self: Pin<&mut Self>, - cx: &mut Context, - stream: bool, - ) -> Poll<Result<T, RecvError>> { - if self.hook.is_some() { - match self.receiver.shared.recv_sync(None) { - Ok(msg) => return Poll::Ready(Ok(msg)), - Err(TryRecvTimeoutError::Disconnected) => { - return Poll::Ready(Err(RecvError::Disconnected)) - } - _ => (), - } - - let hook = self.hook.as_ref().map(Arc::clone).unwrap(); - if hook.update_waker(cx.waker()) { - // If the previous hook was awakened, we need to insert it back to the - // queue, otherwise, it remains valid. - wait_lock(&self.receiver.shared.chan) - .waiting - .push_back(hook); - } - // To avoid a missed wakeup, re-check disconnect status here because the channel might have - // gotten shut down before we had a chance to push our hook - if self.receiver.shared.is_disconnected() { - // And now, to avoid a race condition between the first recv attempt and the disconnect check we - // just performed, attempt to recv again just in case we missed something. - Poll::Ready( - self.receiver - .shared - .recv_sync(None) - .map(Ok) - .unwrap_or(Err(RecvError::Disconnected)), - ) - } else { - Poll::Pending - } - } else { - let mut_self = self.get_mut(); - let (shared, this_hook) = (&mut_self.receiver.shared, &mut mut_self.hook); - - shared.recv( - // should_block - true, - // make_signal - || Hook::trigger(AsyncSignal::new(cx, stream)), - // do_block - |hook| { - *this_hook = Some(hook); - Poll::Pending - }, - ) - .map(|r| r.map_err(|err| match err { - TryRecvTimeoutError::Disconnected => RecvError::Disconnected, - _ => unreachable!(), - })) - } - } - - /// See [`Receiver::is_disconnected`]. - pub fn is_disconnected(&self) -> bool { - self.receiver.is_disconnected() - } - - /// See [`Receiver::is_empty`]. - pub fn is_empty(&self) -> bool { - self.receiver.is_empty() - } - - /// See [`Receiver::is_full`]. - pub fn is_full(&self) -> bool { - self.receiver.is_full() - } - - /// See [`Receiver::len`]. - pub fn len(&self) -> usize { - self.receiver.len() - } - - /// See [`Receiver::capacity`]. - pub fn capacity(&self) -> Option<usize> { - self.receiver.capacity() - } -} - -impl<'a, T> Drop for RecvFut<'a, T> { - fn drop(&mut self) { - self.reset_hook(); - } -} - -impl<'a, T> Future for RecvFut<'a, T> { - type Output = Result<T, RecvError>; - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { - self.poll_inner(cx, false) // stream = false - } -} - -impl<'a, T> FusedFuture for RecvFut<'a, T> { - fn is_terminated(&self) -> bool { - self.receiver.shared.is_disconnected() && self.receiver.shared.is_empty() - } -} - -/// A stream which allows asynchronously receiving messages. -/// -/// Can be created via [`Receiver::stream`] or [`Receiver::into_stream`]. -pub struct RecvStream<'a, T>(RecvFut<'a, T>); - -impl<'a, T> RecvStream<'a, T> { - /// See [`Receiver::is_disconnected`]. - pub fn is_disconnected(&self) -> bool { - self.0.is_disconnected() - } - - /// See [`Receiver::is_empty`]. - pub fn is_empty(&self) -> bool { - self.0.is_empty() - } - - /// See [`Receiver::is_full`]. - pub fn is_full(&self) -> bool { - self.0.is_full() - } - - /// See [`Receiver::len`]. - pub fn len(&self) -> usize { - self.0.len() - } - - /// See [`Receiver::capacity`]. - pub fn capacity(&self) -> Option<usize> { - self.0.capacity() - } - - /// Returns whether the SendSinks are belong to the same channel. - pub fn same_channel(&self, other: &Self) -> bool { - self.0.receiver.same_channel(&*other.0.receiver) - } -} - -impl<'a, T> Clone for RecvStream<'a, T> { - fn clone(&self) -> RecvStream<'a, T> { - RecvStream(RecvFut::new(self.0.receiver.clone())) - } -} - -impl<'a, T> Stream for RecvStream<'a, T> { - type Item = T; - - fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> { - match Pin::new(&mut self.0).poll_inner(cx, true) { // stream = true - Poll::Pending => Poll::Pending, - Poll::Ready(item) => { - self.0.reset_hook(); - Poll::Ready(item.ok()) - } - } - } -} - -impl<'a, T> FusedStream for RecvStream<'a, T> { - fn is_terminated(&self) -> bool { - self.0.is_terminated() - } -} diff --git a/vendor/flume/src/lib.rs b/vendor/flume/src/lib.rs deleted file mode 100644 index c9bb3ee..0000000 --- a/vendor/flume/src/lib.rs +++ /dev/null @@ -1,1142 +0,0 @@ -//! # Flume -//! -//! A blazingly fast multi-producer, multi-consumer channel. -//! -//! *"Do not communicate by sharing memory; instead, share memory by communicating."* -//! -//! ## Why Flume? -//! -//! - **Featureful**: Unbounded, bounded and rendezvous queues -//! - **Fast**: Always faster than `std::sync::mpsc` and sometimes `crossbeam-channel` -//! - **Safe**: No `unsafe` code anywhere in the codebase! -//! - **Flexible**: `Sender` and `Receiver` both implement `Send + Sync + Clone` -//! - **Familiar**: Drop-in replacement for `std::sync::mpsc` -//! - **Capable**: Additional features like MPMC support and send timeouts/deadlines -//! - **Simple**: Few dependencies, minimal codebase, fast to compile -//! - **Asynchronous**: `async` support, including mix 'n match with sync code -//! - **Ergonomic**: Powerful `select`-like interface -//! -//! ## Example -//! -//! ``` -//! let (tx, rx) = flume::unbounded(); -//! -//! tx.send(42).unwrap(); -//! assert_eq!(rx.recv().unwrap(), 42); -//! ``` - -#![deny(missing_docs)] - -#[cfg(feature = "select")] -pub mod select; -#[cfg(feature = "async")] -pub mod r#async; - -mod signal; - -// Reexports -#[cfg(feature = "select")] -pub use select::Selector; - -use std::{ - collections::VecDeque, - sync::{Arc, atomic::{AtomicUsize, AtomicBool, Ordering}, Weak}, - time::{Duration, Instant}, - marker::PhantomData, - thread, - fmt, -}; - -#[cfg(feature = "spin")] -use spin1::{Mutex as Spinlock, MutexGuard as SpinlockGuard}; -use crate::signal::{Signal, SyncSignal}; - -/// An error that may be emitted when attempting to send a value into a channel on a sender when -/// all receivers are dropped. -#[derive(Copy, Clone, PartialEq, Eq)] -pub struct SendError<T>(pub T); - -impl<T> SendError<T> { - /// Consume the error, yielding the message that failed to send. - pub fn into_inner(self) -> T { self.0 } -} - -impl<T> fmt::Debug for SendError<T> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - "SendError(..)".fmt(f) - } -} - -impl<T> fmt::Display for SendError<T> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - "sending on a closed channel".fmt(f) - } -} - -impl<T> std::error::Error for SendError<T> {} - -/// An error that may be emitted when attempting to send a value into a channel on a sender when -/// the channel is full or all receivers are dropped. -#[derive(Copy, Clone, PartialEq, Eq)] -pub enum TrySendError<T> { - /// The channel the message is sent on has a finite capacity and was full when the send was attempted. - Full(T), - /// All channel receivers were dropped and so the message has nobody to receive it. - Disconnected(T), -} - -impl<T> TrySendError<T> { - /// Consume the error, yielding the message that failed to send. - pub fn into_inner(self) -> T { - match self { - Self::Full(msg) | Self::Disconnected(msg) => msg, - } - } -} - -impl<T> fmt::Debug for TrySendError<T> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - TrySendError::Full(..) => "Full(..)".fmt(f), - TrySendError::Disconnected(..) => "Disconnected(..)".fmt(f), - } - } -} - -impl<T> fmt::Display for TrySendError<T> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - TrySendError::Full(..) => "sending on a full channel".fmt(f), - TrySendError::Disconnected(..) => "sending on a closed channel".fmt(f), - } - } -} - -impl<T> std::error::Error for TrySendError<T> {} - -impl<T> From<SendError<T>> for TrySendError<T> { - fn from(err: SendError<T>) -> Self { - match err { - SendError(item) => Self::Disconnected(item), - } - } -} - -/// An error that may be emitted when sending a value into a channel on a sender with a timeout when -/// the send operation times out or all receivers are dropped. -#[derive(Copy, Clone, PartialEq, Eq)] -pub enum SendTimeoutError<T> { - /// A timeout occurred when attempting to send the message. - Timeout(T), - /// All channel receivers were dropped and so the message has nobody to receive it. - Disconnected(T), -} - -impl<T> SendTimeoutError<T> { - /// Consume the error, yielding the message that failed to send. - pub fn into_inner(self) -> T { - match self { - Self::Timeout(msg) | Self::Disconnected(msg) => msg, - } - } -} - -impl<T> fmt::Debug for SendTimeoutError<T> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - "SendTimeoutError(..)".fmt(f) - } -} - -impl<T> fmt::Display for SendTimeoutError<T> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - SendTimeoutError::Timeout(..) => "timed out sending on a full channel".fmt(f), - SendTimeoutError::Disconnected(..) => "sending on a closed channel".fmt(f), - } - } -} - -impl<T> std::error::Error for SendTimeoutError<T> {} - -impl<T> From<SendError<T>> for SendTimeoutError<T> { - fn from(err: SendError<T>) -> Self { - match err { - SendError(item) => Self::Disconnected(item), - } - } -} - -enum TrySendTimeoutError<T> { - Full(T), - Disconnected(T), - Timeout(T), -} - -/// An error that may be emitted when attempting to wait for a value on a receiver when all senders -/// are dropped and there are no more messages in the channel. -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum RecvError { - /// All senders were dropped and no messages are waiting in the channel, so no further messages can be received. - Disconnected, -} - -impl fmt::Display for RecvError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - RecvError::Disconnected => "receiving on a closed channel".fmt(f), - } - } -} - -impl std::error::Error for RecvError {} - -/// An error that may be emitted when attempting to fetch a value on a receiver when there are no -/// messages in the channel. If there are no messages in the channel and all senders are dropped, -/// then `TryRecvError::Disconnected` will be returned. -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum TryRecvError { - /// The channel was empty when the receive was attempted. - Empty, - /// All senders were dropped and no messages are waiting in the channel, so no further messages can be received. - Disconnected, -} - -impl fmt::Display for TryRecvError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - TryRecvError::Empty => "receiving on an empty channel".fmt(f), - TryRecvError::Disconnected => "channel is empty and closed".fmt(f), - } - } -} - -impl std::error::Error for TryRecvError {} - -impl From<RecvError> for TryRecvError { - fn from(err: RecvError) -> Self { - match err { - RecvError::Disconnected => Self::Disconnected, - } - } -} - -/// An error that may be emitted when attempting to wait for a value on a receiver with a timeout -/// when the receive operation times out or all senders are dropped and there are no values left -/// in the channel. -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum RecvTimeoutError { - /// A timeout occurred when attempting to receive a message. - Timeout, - /// All senders were dropped and no messages are waiting in the channel, so no further messages can be received. - Disconnected, -} - -impl fmt::Display for RecvTimeoutError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - RecvTimeoutError::Timeout => "timed out waiting on a channel".fmt(f), - RecvTimeoutError::Disconnected => "channel is empty and closed".fmt(f), - } - } -} - -impl std::error::Error for RecvTimeoutError {} - -impl From<RecvError> for RecvTimeoutError { - fn from(err: RecvError) -> Self { - match err { - RecvError::Disconnected => Self::Disconnected, - } - } -} - -enum TryRecvTimeoutError { - Empty, - Timeout, - Disconnected, -} - -// TODO: Investigate some sort of invalidation flag for timeouts -#[cfg(feature = "spin")] -struct Hook<T, S: ?Sized>(Option<Spinlock<Option<T>>>, S); - -#[cfg(not(feature = "spin"))] -struct Hook<T, S: ?Sized>(Option<Mutex<Option<T>>>, S); - -#[cfg(feature = "spin")] -impl<T, S: ?Sized + Signal> Hook<T, S> { - pub fn slot(msg: Option<T>, signal: S) -> Arc<Self> - where - S: Sized, - { - Arc::new(Self(Some(Spinlock::new(msg)), signal)) - } - - fn lock(&self) -> Option<SpinlockGuard<'_, Option<T>>> { - self.0.as_ref().map(|s| s.lock()) - } -} - -#[cfg(not(feature = "spin"))] -impl<T, S: ?Sized + Signal> Hook<T, S> { - pub fn slot(msg: Option<T>, signal: S) -> Arc<Self> - where - S: Sized, - { - Arc::new(Self(Some(Mutex::new(msg)), signal)) - } - - fn lock(&self) -> Option<MutexGuard<'_, Option<T>>> { - self.0.as_ref().map(|s| s.lock().unwrap()) - } -} - -impl<T, S: ?Sized + Signal> Hook<T, S> { - pub fn fire_recv(&self) -> (T, &S) { - let msg = self.lock().unwrap().take().unwrap(); - (msg, self.signal()) - } - - pub fn fire_send(&self, msg: T) -> (Option<T>, &S) { - let ret = match self.lock() { - Some(mut lock) => { - *lock = Some(msg); - None - } - None => Some(msg), - }; - (ret, self.signal()) - } - - pub fn is_empty(&self) -> bool { - self.lock().map(|s| s.is_none()).unwrap_or(true) - } - - pub fn try_take(&self) -> Option<T> { - self.lock().unwrap().take() - } - - pub fn trigger(signal: S) -> Arc<Self> - where - S: Sized, - { - Arc::new(Self(None, signal)) - } - - pub fn signal(&self) -> &S { - &self.1 - } - - pub fn fire_nothing(&self) -> bool { - self.signal().fire() - } -} - -impl<T> Hook<T, SyncSignal> { - pub fn wait_recv(&self, abort: &AtomicBool) -> Option<T> { - loop { - let disconnected = abort.load(Ordering::SeqCst); // Check disconnect *before* msg - let msg = self.lock().unwrap().take(); - if let Some(msg) = msg { - break Some(msg); - } else if disconnected { - break None; - } else { - self.signal().wait() - } - } - } - - // Err(true) if timeout - pub fn wait_deadline_recv(&self, abort: &AtomicBool, deadline: Instant) -> Result<T, bool> { - loop { - let disconnected = abort.load(Ordering::SeqCst); // Check disconnect *before* msg - let msg = self.lock().unwrap().take(); - if let Some(msg) = msg { - break Ok(msg); - } else if disconnected { - break Err(false); - } else if let Some(dur) = deadline.checked_duration_since(Instant::now()) { - self.signal().wait_timeout(dur); - } else { - break Err(true); - } - } - } - - pub fn wait_send(&self, abort: &AtomicBool) { - loop { - let disconnected = abort.load(Ordering::SeqCst); // Check disconnect *before* msg - if disconnected || self.lock().unwrap().is_none() { - break; - } - - self.signal().wait(); - } - } - - // Err(true) if timeout - pub fn wait_deadline_send(&self, abort: &AtomicBool, deadline: Instant) -> Result<(), bool> { - loop { - let disconnected = abort.load(Ordering::SeqCst); // Check disconnect *before* msg - if self.lock().unwrap().is_none() { - break Ok(()); - } else if disconnected { - break Err(false); - } else if let Some(dur) = deadline.checked_duration_since(Instant::now()) { - self.signal().wait_timeout(dur); - } else { - break Err(true); - } - } - } -} - -#[cfg(feature = "spin")] -#[inline] -fn wait_lock<T>(lock: &Spinlock<T>) -> SpinlockGuard<T> { - let mut i = 4; - loop { - for _ in 0..10 { - if let Some(guard) = lock.try_lock() { - return guard; - } - thread::yield_now(); - } - // Sleep for at most ~1 ms - thread::sleep(Duration::from_nanos(1 << i.min(20))); - i += 1; - } -} - -#[cfg(not(feature = "spin"))] -#[inline] -fn wait_lock<'a, T>(lock: &'a Mutex<T>) -> MutexGuard<'a, T> { - lock.lock().unwrap() -} - -#[cfg(not(feature = "spin"))] -use std::sync::{Mutex, MutexGuard}; - -#[cfg(feature = "spin")] -type ChanLock<T> = Spinlock<T>; -#[cfg(not(feature = "spin"))] -type ChanLock<T> = Mutex<T>; - - -type SignalVec<T> = VecDeque<Arc<Hook<T, dyn signal::Signal>>>; -struct Chan<T> { - sending: Option<(usize, SignalVec<T>)>, - queue: VecDeque<T>, - waiting: SignalVec<T>, -} - -impl<T> Chan<T> { - fn pull_pending(&mut self, pull_extra: bool) { - if let Some((cap, sending)) = &mut self.sending { - let effective_cap = *cap + pull_extra as usize; - - while self.queue.len() < effective_cap { - if let Some(s) = sending.pop_front() { - let (msg, signal) = s.fire_recv(); - signal.fire(); - self.queue.push_back(msg); - } else { - break; - } - } - } - } - - fn try_wake_receiver_if_pending(&mut self) { - if !self.queue.is_empty() { - while Some(false) == self.waiting.pop_front().map(|s| s.fire_nothing()) {} - } - } -} - -struct Shared<T> { - chan: ChanLock<Chan<T>>, - disconnected: AtomicBool, - sender_count: AtomicUsize, - receiver_count: AtomicUsize, -} - -impl<T> Shared<T> { - fn new(cap: Option<usize>) -> Self { - Self { - chan: ChanLock::new(Chan { - sending: cap.map(|cap| (cap, VecDeque::new())), - queue: VecDeque::new(), - waiting: VecDeque::new(), - }), - disconnected: AtomicBool::new(false), - sender_count: AtomicUsize::new(1), - receiver_count: AtomicUsize::new(1), - } - } - - fn send<S: Signal, R: From<Result<(), TrySendTimeoutError<T>>>>( - &self, - msg: T, - should_block: bool, - make_signal: impl FnOnce(T) -> Arc<Hook<T, S>>, - do_block: impl FnOnce(Arc<Hook<T, S>>) -> R, - ) -> R { - let mut chan = wait_lock(&self.chan); - - if self.is_disconnected() { - Err(TrySendTimeoutError::Disconnected(msg)).into() - } else if !chan.waiting.is_empty() { - let mut msg = Some(msg); - - loop { - let slot = chan.waiting.pop_front(); - match slot.as_ref().map(|r| r.fire_send(msg.take().unwrap())) { - // No more waiting receivers and msg in queue, so break out of the loop - None if msg.is_none() => break, - // No more waiting receivers, so add msg to queue and break out of the loop - None => { - chan.queue.push_back(msg.unwrap()); - break; - } - Some((Some(m), signal)) => { - if signal.fire() { - // Was async and a stream, so didn't acquire the message. Wake another - // receiver, and do not yet push the message. - msg.replace(m); - continue; - } else { - // Was async and not a stream, so it did acquire the message. Push the - // message to the queue for it to be received. - chan.queue.push_back(m); - drop(chan); - break; - } - }, - Some((None, signal)) => { - drop(chan); - signal.fire(); - break; // Was sync, so it has acquired the message - }, - } - } - - Ok(()).into() - } else if chan.sending.as_ref().map(|(cap, _)| chan.queue.len() < *cap).unwrap_or(true) { - chan.queue.push_back(msg); - Ok(()).into() - } else if should_block { // Only bounded from here on - let hook = make_signal(msg); - chan.sending.as_mut().unwrap().1.push_back(hook.clone()); - drop(chan); - - do_block(hook) - } else { - Err(TrySendTimeoutError::Full(msg)).into() - } - } - - fn send_sync( - &self, - msg: T, - block: Option<Option<Instant>>, - ) -> Result<(), TrySendTimeoutError<T>> { - self.send( - // msg - msg, - // should_block - block.is_some(), - // make_signal - |msg| Hook::slot(Some(msg), SyncSignal::default()), - // do_block - |hook| if let Some(deadline) = block.unwrap() { - hook.wait_deadline_send(&self.disconnected, deadline) - .or_else(|timed_out| { - if timed_out { // Remove our signal - let hook: Arc<Hook<T, dyn signal::Signal>> = hook.clone(); - wait_lock(&self.chan).sending - .as_mut() - .unwrap().1 - .retain(|s| s.signal().as_ptr() != hook.signal().as_ptr()); - } - hook.try_take().map(|msg| if self.is_disconnected() { - Err(TrySendTimeoutError::Disconnected(msg)) - } else { - Err(TrySendTimeoutError::Timeout(msg)) - }) - .unwrap_or(Ok(())) - }) - } else { - hook.wait_send(&self.disconnected); - - match hook.try_take() { - Some(msg) => Err(TrySendTimeoutError::Disconnected(msg)), - None => Ok(()), - } - }, - ) - } - - fn recv<S: Signal, R: From<Result<T, TryRecvTimeoutError>>>( - &self, - should_block: bool, - make_signal: impl FnOnce() -> Arc<Hook<T, S>>, - do_block: impl FnOnce(Arc<Hook<T, S>>) -> R, - ) -> R { - let mut chan = wait_lock(&self.chan); - chan.pull_pending(true); - - if let Some(msg) = chan.queue.pop_front() { - drop(chan); - Ok(msg).into() - } else if self.is_disconnected() { - drop(chan); - Err(TryRecvTimeoutError::Disconnected).into() - } else if should_block { - let hook = make_signal(); - chan.waiting.push_back(hook.clone()); - drop(chan); - - do_block(hook) - } else { - drop(chan); - Err(TryRecvTimeoutError::Empty).into() - } - } - - fn recv_sync(&self, block: Option<Option<Instant>>) -> Result<T, TryRecvTimeoutError> { - self.recv( - // should_block - block.is_some(), - // make_signal - || Hook::slot(None, SyncSignal::default()), - // do_block - |hook| if let Some(deadline) = block.unwrap() { - hook.wait_deadline_recv(&self.disconnected, deadline) - .or_else(|timed_out| { - if timed_out { // Remove our signal - let hook: Arc<Hook<T, dyn Signal>> = hook.clone(); - wait_lock(&self.chan).waiting - .retain(|s| s.signal().as_ptr() != hook.signal().as_ptr()); - } - match hook.try_take() { - Some(msg) => Ok(msg), - None => { - let disconnected = self.is_disconnected(); // Check disconnect *before* msg - if let Some(msg) = wait_lock(&self.chan).queue.pop_front() { - Ok(msg) - } else if disconnected { - Err(TryRecvTimeoutError::Disconnected) - } else { - Err(TryRecvTimeoutError::Timeout) - } - }, - } - }) - } else { - hook.wait_recv(&self.disconnected) - .or_else(|| wait_lock(&self.chan).queue.pop_front()) - .ok_or(TryRecvTimeoutError::Disconnected) - }, - ) - } - - /// Disconnect anything listening on this channel (this will not prevent receivers receiving - /// msgs that have already been sent) - fn disconnect_all(&self) { - self.disconnected.store(true, Ordering::Relaxed); - - let mut chan = wait_lock(&self.chan); - chan.pull_pending(false); - if let Some((_, sending)) = chan.sending.as_ref() { - sending.iter().for_each(|hook| { - hook.signal().fire(); - }) - } - chan.waiting.iter().for_each(|hook| { - hook.signal().fire(); - }); - } - - fn is_disconnected(&self) -> bool { - self.disconnected.load(Ordering::SeqCst) - } - - fn is_empty(&self) -> bool { - self.len() == 0 - } - - fn is_full(&self) -> bool { - self.capacity().map(|cap| cap == self.len()).unwrap_or(false) - } - - fn len(&self) -> usize { - let mut chan = wait_lock(&self.chan); - chan.pull_pending(false); - chan.queue.len() - } - - fn capacity(&self) -> Option<usize> { - wait_lock(&self.chan).sending.as_ref().map(|(cap, _)| *cap) - } - - fn sender_count(&self) -> usize { - self.sender_count.load(Ordering::Relaxed) - } - - fn receiver_count(&self) -> usize { - self.receiver_count.load(Ordering::Relaxed) - } -} - -/// A transmitting end of a channel. -pub struct Sender<T> { - shared: Arc<Shared<T>>, -} - -impl<T> Sender<T> { - /// Attempt to send a value into the channel. If the channel is bounded and full, or all - /// receivers have been dropped, an error is returned. If the channel associated with this - /// sender is unbounded, this method has the same behaviour as [`Sender::send`]. - pub fn try_send(&self, msg: T) -> Result<(), TrySendError<T>> { - self.shared.send_sync(msg, None).map_err(|err| match err { - TrySendTimeoutError::Full(msg) => TrySendError::Full(msg), - TrySendTimeoutError::Disconnected(msg) => TrySendError::Disconnected(msg), - _ => unreachable!(), - }) - } - - /// Send a value into the channel, returning an error if all receivers have been dropped. - /// If the channel is bounded and is full, this method will block until space is available - /// or all receivers have been dropped. If the channel is unbounded, this method will not - /// block. - pub fn send(&self, msg: T) -> Result<(), SendError<T>> { - self.shared.send_sync(msg, Some(None)).map_err(|err| match err { - TrySendTimeoutError::Disconnected(msg) => SendError(msg), - _ => unreachable!(), - }) - } - - /// Send a value into the channel, returning an error if all receivers have been dropped - /// or the deadline has passed. If the channel is bounded and is full, this method will - /// block until space is available, the deadline is reached, or all receivers have been - /// dropped. - pub fn send_deadline(&self, msg: T, deadline: Instant) -> Result<(), SendTimeoutError<T>> { - self.shared.send_sync(msg, Some(Some(deadline))).map_err(|err| match err { - TrySendTimeoutError::Disconnected(msg) => SendTimeoutError::Disconnected(msg), - TrySendTimeoutError::Timeout(msg) => SendTimeoutError::Timeout(msg), - _ => unreachable!(), - }) - } - - /// Send a value into the channel, returning an error if all receivers have been dropped - /// or the timeout has expired. If the channel is bounded and is full, this method will - /// block until space is available, the timeout has expired, or all receivers have been - /// dropped. - pub fn send_timeout(&self, msg: T, dur: Duration) -> Result<(), SendTimeoutError<T>> { - self.send_deadline(msg, Instant::now().checked_add(dur).unwrap()) - } - - /// Returns true if all receivers for this channel have been dropped. - pub fn is_disconnected(&self) -> bool { - self.shared.is_disconnected() - } - - /// Returns true if the channel is empty. - /// Note: Zero-capacity channels are always empty. - pub fn is_empty(&self) -> bool { - self.shared.is_empty() - } - - /// Returns true if the channel is full. - /// Note: Zero-capacity channels are always full. - pub fn is_full(&self) -> bool { - self.shared.is_full() - } - - /// Returns the number of messages in the channel - pub fn len(&self) -> usize { - self.shared.len() - } - - /// If the channel is bounded, returns its capacity. - pub fn capacity(&self) -> Option<usize> { - self.shared.capacity() - } - - /// Get the number of senders that currently exist, including this one. - pub fn sender_count(&self) -> usize { - self.shared.sender_count() - } - - /// Get the number of receivers that currently exist. - /// - /// Note that this method makes no guarantees that a subsequent send will succeed; it's - /// possible that between `receiver_count()` being called and a `send()`, all open receivers - /// could drop. - pub fn receiver_count(&self) -> usize { - self.shared.receiver_count() - } - - /// Creates a [`WeakSender`] that does not keep the channel open. - /// - /// The channel is closed once all `Sender`s are dropped, even if there - /// are still active `WeakSender`s. - pub fn downgrade(&self) -> WeakSender<T> { - WeakSender { - shared: Arc::downgrade(&self.shared), - } - } - - /// Returns whether the senders are belong to the same channel. - pub fn same_channel(&self, other: &Sender<T>) -> bool { - Arc::ptr_eq(&self.shared, &other.shared) - } -} - -impl<T> Clone for Sender<T> { - /// Clone this sender. [`Sender`] acts as a handle to the ending a channel. Remaining channel - /// contents will only be cleaned up when all senders and the receiver have been dropped. - fn clone(&self) -> Self { - self.shared.sender_count.fetch_add(1, Ordering::Relaxed); - Self { shared: self.shared.clone() } - } -} - -impl<T> fmt::Debug for Sender<T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Sender").finish() - } -} - -impl<T> Drop for Sender<T> { - fn drop(&mut self) { - // Notify receivers that all senders have been dropped if the number of senders drops to 0. - if self.shared.sender_count.fetch_sub(1, Ordering::Relaxed) == 1 { - self.shared.disconnect_all(); - } - } -} - -/// A sender that does not prevent the channel from being closed. -/// -/// Weak senders do not count towards the number of active senders on the channel. As soon as -/// all normal [`Sender`]s are dropped, the channel is closed, even if there is still a -/// `WeakSender`. -/// -/// To send messages, a `WeakSender` must first be upgraded to a `Sender` using the [`upgrade`] -/// method. -pub struct WeakSender<T> { - shared: Weak<Shared<T>>, -} - -impl<T> WeakSender<T> { - /// Tries to upgrade the `WeakSender` to a [`Sender`], in order to send messages. - /// - /// Returns `None` if the channel was closed already. Note that a `Some` return value - /// does not guarantee that the channel is still open. - pub fn upgrade(&self) -> Option<Sender<T>> { - self.shared - .upgrade() - // check that there are still live senders - .filter(|shared| { - shared - .sender_count - .fetch_update(Ordering::Relaxed, Ordering::Relaxed, |count| { - if count == 0 { - // all senders are closed already -> don't increase the sender count - None - } else { - // there is still at least one active sender - Some(count + 1) - } - }) - .is_ok() - }) - .map(|shared| Sender { shared }) - } -} - -/// The receiving end of a channel. -/// -/// Note: Cloning the receiver *does not* turn this channel into a broadcast channel. -/// Each message will only be received by a single receiver. This is useful for -/// implementing work stealing for concurrent programs. -pub struct Receiver<T> { - shared: Arc<Shared<T>>, -} - -impl<T> Receiver<T> { - /// Attempt to fetch an incoming value from the channel associated with this receiver, - /// returning an error if the channel is empty or if all senders have been dropped. - pub fn try_recv(&self) -> Result<T, TryRecvError> { - self.shared.recv_sync(None).map_err(|err| match err { - TryRecvTimeoutError::Disconnected => TryRecvError::Disconnected, - TryRecvTimeoutError::Empty => TryRecvError::Empty, - _ => unreachable!(), - }) - } - - /// Wait for an incoming value from the channel associated with this receiver, returning an - /// error if all senders have been dropped. - pub fn recv(&self) -> Result<T, RecvError> { - self.shared.recv_sync(Some(None)).map_err(|err| match err { - TryRecvTimeoutError::Disconnected => RecvError::Disconnected, - _ => unreachable!(), - }) - } - - /// Wait for an incoming value from the channel associated with this receiver, returning an - /// error if all senders have been dropped or the deadline has passed. - pub fn recv_deadline(&self, deadline: Instant) -> Result<T, RecvTimeoutError> { - self.shared.recv_sync(Some(Some(deadline))).map_err(|err| match err { - TryRecvTimeoutError::Disconnected => RecvTimeoutError::Disconnected, - TryRecvTimeoutError::Timeout => RecvTimeoutError::Timeout, - _ => unreachable!(), - }) - } - - /// Wait for an incoming value from the channel associated with this receiver, returning an - /// error if all senders have been dropped or the timeout has expired. - pub fn recv_timeout(&self, dur: Duration) -> Result<T, RecvTimeoutError> { - self.recv_deadline(Instant::now().checked_add(dur).unwrap()) - } - - /// Create a blocking iterator over the values received on the channel that finishes iteration - /// when all senders have been dropped. - /// - /// You can also create a self-owned iterator with [`Receiver::into_iter`]. - pub fn iter(&self) -> Iter<T> { - Iter { receiver: &self } - } - - /// A non-blocking iterator over the values received on the channel that finishes iteration - /// when all senders have been dropped or the channel is empty. - pub fn try_iter(&self) -> TryIter<T> { - TryIter { receiver: &self } - } - - /// Take all msgs currently sitting in the channel and produce an iterator over them. Unlike - /// `try_iter`, the iterator will not attempt to fetch any more values from the channel once - /// the function has been called. - pub fn drain(&self) -> Drain<T> { - let mut chan = wait_lock(&self.shared.chan); - chan.pull_pending(false); - let queue = std::mem::take(&mut chan.queue); - - Drain { queue, _phantom: PhantomData } - } - - /// Returns true if all senders for this channel have been dropped. - pub fn is_disconnected(&self) -> bool { - self.shared.is_disconnected() - } - - /// Returns true if the channel is empty. - /// Note: Zero-capacity channels are always empty. - pub fn is_empty(&self) -> bool { - self.shared.is_empty() - } - - /// Returns true if the channel is full. - /// Note: Zero-capacity channels are always full. - pub fn is_full(&self) -> bool { - self.shared.is_full() - } - - /// Returns the number of messages in the channel. - pub fn len(&self) -> usize { - self.shared.len() - } - - /// If the channel is bounded, returns its capacity. - pub fn capacity(&self) -> Option<usize> { - self.shared.capacity() - } - - /// Get the number of senders that currently exist. - pub fn sender_count(&self) -> usize { - self.shared.sender_count() - } - - /// Get the number of receivers that currently exist, including this one. - pub fn receiver_count(&self) -> usize { - self.shared.receiver_count() - } - - /// Returns whether the receivers are belong to the same channel. - pub fn same_channel(&self, other: &Receiver<T>) -> bool { - Arc::ptr_eq(&self.shared, &other.shared) - } -} - -impl<T> Clone for Receiver<T> { - /// Clone this receiver. [`Receiver`] acts as a handle to the ending a channel. Remaining - /// channel contents will only be cleaned up when all senders and the receiver have been - /// dropped. - /// - /// Note: Cloning the receiver *does not* turn this channel into a broadcast channel. - /// Each message will only be received by a single receiver. This is useful for - /// implementing work stealing for concurrent programs. - fn clone(&self) -> Self { - self.shared.receiver_count.fetch_add(1, Ordering::Relaxed); - Self { shared: self.shared.clone() } - } -} - -impl<T> fmt::Debug for Receiver<T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Receiver").finish() - } -} - -impl<T> Drop for Receiver<T> { - fn drop(&mut self) { - // Notify senders that all receivers have been dropped if the number of receivers drops - // to 0. - if self.shared.receiver_count.fetch_sub(1, Ordering::Relaxed) == 1 { - self.shared.disconnect_all(); - } - } -} - -/// This exists as a shorthand for [`Receiver::iter`]. -impl<'a, T> IntoIterator for &'a Receiver<T> { - type Item = T; - type IntoIter = Iter<'a, T>; - - fn into_iter(self) -> Self::IntoIter { - Iter { receiver: self } - } -} - -impl<T> IntoIterator for Receiver<T> { - type Item = T; - type IntoIter = IntoIter<T>; - - /// Creates a self-owned but semantically equivalent alternative to [`Receiver::iter`]. - fn into_iter(self) -> Self::IntoIter { - IntoIter { receiver: self } - } -} - -/// An iterator over the msgs received from a channel. -pub struct Iter<'a, T> { - receiver: &'a Receiver<T>, -} - -impl<'a, T> Iterator for Iter<'a, T> { - type Item = T; - - fn next(&mut self) -> Option<Self::Item> { - self.receiver.recv().ok() - } -} - -/// An non-blocking iterator over the msgs received from a channel. -pub struct TryIter<'a, T> { - receiver: &'a Receiver<T>, -} - -impl<'a, T> Iterator for TryIter<'a, T> { - type Item = T; - - fn next(&mut self) -> Option<Self::Item> { - self.receiver.try_recv().ok() - } -} - -/// An fixed-sized iterator over the msgs drained from a channel. -#[derive(Debug)] -pub struct Drain<'a, T> { - queue: VecDeque<T>, - /// A phantom field used to constrain the lifetime of this iterator. We do this because the - /// implementation may change and we don't want to unintentionally constrain it. Removing this - /// lifetime later is a possibility. - _phantom: PhantomData<&'a ()>, -} - -impl<'a, T> Iterator for Drain<'a, T> { - type Item = T; - - fn next(&mut self) -> Option<Self::Item> { - self.queue.pop_front() - } -} - -impl<'a, T> ExactSizeIterator for Drain<'a, T> { - fn len(&self) -> usize { - self.queue.len() - } -} - -/// An owned iterator over the msgs received from a channel. -pub struct IntoIter<T> { - receiver: Receiver<T>, -} - -impl<T> Iterator for IntoIter<T> { - type Item = T; - - fn next(&mut self) -> Option<Self::Item> { - self.receiver.recv().ok() - } -} - -/// Create a channel with no maximum capacity. -/// -/// Create an unbounded channel with a [`Sender`] and [`Receiver`] connected to each end respectively. Values sent in -/// one end of the channel will be received on the other end. The channel is thread-safe, and both [`Sender`] and -/// [`Receiver`] may be sent to or shared between threads as necessary. In addition, both [`Sender`] and [`Receiver`] -/// may be cloned. -/// -/// # Examples -/// ``` -/// let (tx, rx) = flume::unbounded(); -/// -/// tx.send(42).unwrap(); -/// assert_eq!(rx.recv().unwrap(), 42); -/// ``` -pub fn unbounded<T>() -> (Sender<T>, Receiver<T>) { - let shared = Arc::new(Shared::new(None)); - ( - Sender { shared: shared.clone() }, - Receiver { shared }, - ) -} - -/// Create a channel with a maximum capacity. -/// -/// Create a bounded channel with a [`Sender`] and [`Receiver`] connected to each end respectively. Values sent in one -/// end of the channel will be received on the other end. The channel is thread-safe, and both [`Sender`] and -/// [`Receiver`] may be sent to or shared between threads as necessary. In addition, both [`Sender`] and [`Receiver`] -/// may be cloned. -/// -/// Unlike an [`unbounded`] channel, if there is no space left for new messages, calls to -/// [`Sender::send`] will block (unblocking once a receiver has made space). If blocking behaviour -/// is not desired, [`Sender::try_send`] may be used. -/// -/// Like `std::sync::mpsc`, `flume` supports 'rendezvous' channels. A bounded queue with a maximum capacity of zero -/// will block senders until a receiver is available to take the value. You can imagine a rendezvous channel as a -/// ['Glienicke Bridge'](https://en.wikipedia.org/wiki/Glienicke_Bridge)-style location at which senders and receivers -/// perform a handshake and transfer ownership of a value. -/// -/// # Examples -/// ``` -/// let (tx, rx) = flume::bounded(32); -/// -/// for i in 1..33 { -/// tx.send(i).unwrap(); -/// } -/// assert!(tx.try_send(33).is_err()); -/// -/// assert_eq!(rx.try_iter().sum::<u32>(), (1..33).sum()); -/// ``` -pub fn bounded<T>(cap: usize) -> (Sender<T>, Receiver<T>) { - let shared = Arc::new(Shared::new(Some(cap))); - ( - Sender { shared: shared.clone() }, - Receiver { shared }, - ) -} diff --git a/vendor/flume/src/select.rs b/vendor/flume/src/select.rs deleted file mode 100644 index cef15aa..0000000 --- a/vendor/flume/src/select.rs +++ /dev/null @@ -1,405 +0,0 @@ -//! Types that permit waiting upon multiple blocking operations using the [`Selector`] interface. - -use crate::*; -use spin1::Mutex as Spinlock; -use std::{any::Any, marker::PhantomData}; - -#[cfg(feature = "eventual-fairness")] -use nanorand::Rng; - -// A unique token corresponding to an event in a selector -type Token = usize; - -struct SelectSignal( - thread::Thread, - Token, - AtomicBool, - Arc<Spinlock<VecDeque<Token>>>, -); - -impl Signal for SelectSignal { - fn fire(&self) -> bool { - self.2.store(true, Ordering::SeqCst); - self.3.lock().push_back(self.1); - self.0.unpark(); - false - } - - fn as_any(&self) -> &(dyn Any + 'static) { - self - } - fn as_ptr(&self) -> *const () { - self as *const _ as *const () - } -} - -trait Selection<'a, T> { - fn init(&mut self) -> Option<T>; - fn poll(&mut self) -> Option<T>; - fn deinit(&mut self); -} - -/// An error that may be emitted when attempting to wait for a value on a receiver. -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum SelectError { - /// A timeout occurred when waiting on a `Selector`. - Timeout, -} - -impl fmt::Display for SelectError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - SelectError::Timeout => "timeout occurred".fmt(f), - } - } -} - -impl std::error::Error for SelectError {} - -/// A type used to wait upon multiple blocking operations at once. -/// -/// A [`Selector`] implements [`select`](https://en.wikipedia.org/wiki/Select_(Unix))-like behaviour, -/// allowing a thread to wait upon the result of more than one operation at once. -/// -/// # Examples -/// ``` -/// let (tx0, rx0) = flume::unbounded(); -/// let (tx1, rx1) = flume::unbounded(); -/// -/// std::thread::spawn(move || { -/// tx0.send(true).unwrap(); -/// tx1.send(42).unwrap(); -/// }); -/// -/// flume::Selector::new() -/// .recv(&rx0, |b| println!("Received {:?}", b)) -/// .recv(&rx1, |n| println!("Received {:?}", n)) -/// .wait(); -/// ``` -pub struct Selector<'a, T: 'a> { - selections: Vec<Box<dyn Selection<'a, T> + 'a>>, - next_poll: usize, - signalled: Arc<Spinlock<VecDeque<Token>>>, - #[cfg(feature = "eventual-fairness")] - rng: nanorand::WyRand, - phantom: PhantomData<*const ()>, -} - -impl<'a, T: 'a> Default for Selector<'a, T> { - fn default() -> Self { - Self::new() - } -} - -impl<'a, T: 'a> fmt::Debug for Selector<'a, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Selector").finish() - } -} - -impl<'a, T> Selector<'a, T> { - /// Create a new selector. - pub fn new() -> Self { - Self { - selections: Vec::new(), - next_poll: 0, - signalled: Arc::default(), - phantom: PhantomData::default(), - #[cfg(feature = "eventual-fairness")] - rng: nanorand::WyRand::new(), - } - } - - /// Add a send operation to the selector that sends the provided value. - /// - /// Once added, the selector can be used to run the provided handler function on completion of this operation. - pub fn send<U, F: FnMut(Result<(), SendError<U>>) -> T + 'a>( - mut self, - sender: &'a Sender<U>, - msg: U, - mapper: F, - ) -> Self { - struct SendSelection<'a, T, F, U> { - sender: &'a Sender<U>, - msg: Option<U>, - token: Token, - signalled: Arc<Spinlock<VecDeque<Token>>>, - hook: Option<Arc<Hook<U, SelectSignal>>>, - mapper: F, - phantom: PhantomData<T>, - } - - impl<'a, T, F, U> Selection<'a, T> for SendSelection<'a, T, F, U> - where - F: FnMut(Result<(), SendError<U>>) -> T, - { - fn init(&mut self) -> Option<T> { - let token = self.token; - let signalled = self.signalled.clone(); - let r = self.sender.shared.send( - self.msg.take().unwrap(), - true, - |msg| { - Hook::slot( - Some(msg), - SelectSignal( - thread::current(), - token, - AtomicBool::new(false), - signalled, - ), - ) - }, - // Always runs - |h| { - self.hook = Some(h); - Ok(()) - }, - ); - - if self.hook.is_none() { - Some((self.mapper)(match r { - Ok(()) => Ok(()), - Err(TrySendTimeoutError::Disconnected(msg)) => Err(SendError(msg)), - _ => unreachable!(), - })) - } else { - None - } - } - - fn poll(&mut self) -> Option<T> { - let res = if self.sender.shared.is_disconnected() { - // Check the hook one last time - if let Some(msg) = self.hook.as_ref()?.try_take() { - Err(SendError(msg)) - } else { - Ok(()) - } - } else if self.hook.as_ref().unwrap().is_empty() { - // The message was sent - Ok(()) - } else { - return None; - }; - - Some((&mut self.mapper)(res)) - } - - fn deinit(&mut self) { - if let Some(hook) = self.hook.take() { - // Remove hook - let hook: Arc<Hook<U, dyn Signal>> = hook; - wait_lock(&self.sender.shared.chan) - .sending - .as_mut() - .unwrap() - .1 - .retain(|s| s.signal().as_ptr() != hook.signal().as_ptr()); - } - } - } - - let token = self.selections.len(); - self.selections.push(Box::new(SendSelection { - sender, - msg: Some(msg), - token, - signalled: self.signalled.clone(), - hook: None, - mapper, - phantom: Default::default(), - })); - - self - } - - /// Add a receive operation to the selector. - /// - /// Once added, the selector can be used to run the provided handler function on completion of this operation. - pub fn recv<U, F: FnMut(Result<U, RecvError>) -> T + 'a>( - mut self, - receiver: &'a Receiver<U>, - mapper: F, - ) -> Self { - struct RecvSelection<'a, T, F, U> { - receiver: &'a Receiver<U>, - token: Token, - signalled: Arc<Spinlock<VecDeque<Token>>>, - hook: Option<Arc<Hook<U, SelectSignal>>>, - mapper: F, - received: bool, - phantom: PhantomData<T>, - } - - impl<'a, T, F, U> Selection<'a, T> for RecvSelection<'a, T, F, U> - where - F: FnMut(Result<U, RecvError>) -> T, - { - fn init(&mut self) -> Option<T> { - let token = self.token; - let signalled = self.signalled.clone(); - let r = self.receiver.shared.recv( - true, - || { - Hook::trigger(SelectSignal( - thread::current(), - token, - AtomicBool::new(false), - signalled, - )) - }, - // Always runs - |h| { - self.hook = Some(h); - Err(TryRecvTimeoutError::Timeout) - }, - ); - - if self.hook.is_none() { - Some((self.mapper)(match r { - Ok(msg) => Ok(msg), - Err(TryRecvTimeoutError::Disconnected) => Err(RecvError::Disconnected), - _ => unreachable!(), - })) - } else { - None - } - } - - fn poll(&mut self) -> Option<T> { - let res = if let Ok(msg) = self.receiver.try_recv() { - self.received = true; - Ok(msg) - } else if self.receiver.shared.is_disconnected() { - Err(RecvError::Disconnected) - } else { - return None; - }; - - Some((&mut self.mapper)(res)) - } - - fn deinit(&mut self) { - if let Some(hook) = self.hook.take() { - // Remove hook - let hook: Arc<Hook<U, dyn Signal>> = hook; - wait_lock(&self.receiver.shared.chan) - .waiting - .retain(|s| s.signal().as_ptr() != hook.signal().as_ptr()); - // If we were woken, but never polled, wake up another - if !self.received - && hook - .signal() - .as_any() - .downcast_ref::<SelectSignal>() - .unwrap() - .2 - .load(Ordering::SeqCst) - { - wait_lock(&self.receiver.shared.chan).try_wake_receiver_if_pending(); - } - } - } - } - - let token = self.selections.len(); - self.selections.push(Box::new(RecvSelection { - receiver, - token, - signalled: self.signalled.clone(), - hook: None, - mapper, - received: false, - phantom: Default::default(), - })); - - self - } - - fn wait_inner(mut self, deadline: Option<Instant>) -> Option<T> { - #[cfg(feature = "eventual-fairness")] - { - self.next_poll = self.rng.generate_range(0..self.selections.len()); - } - - let res = 'outer: loop { - // Init signals - for _ in 0..self.selections.len() { - if let Some(val) = self.selections[self.next_poll].init() { - break 'outer Some(val); - } - self.next_poll = (self.next_poll + 1) % self.selections.len(); - } - - // Speculatively poll - if let Some(msg) = self.poll() { - break 'outer Some(msg); - } - - loop { - if let Some(deadline) = deadline { - if let Some(dur) = deadline.checked_duration_since(Instant::now()) { - thread::park_timeout(dur); - } - } else { - thread::park(); - } - - if deadline.map(|d| Instant::now() >= d).unwrap_or(false) { - break 'outer self.poll(); - } - - let token = if let Some(token) = self.signalled.lock().pop_front() { - token - } else { - // Spurious wakeup, park again - continue; - }; - - // Attempt to receive a message - if let Some(msg) = self.selections[token].poll() { - break 'outer Some(msg); - } - } - }; - - // Deinit signals - for s in &mut self.selections { - s.deinit(); - } - - res - } - - fn poll(&mut self) -> Option<T> { - for _ in 0..self.selections.len() { - if let Some(val) = self.selections[self.next_poll].poll() { - return Some(val); - } - self.next_poll = (self.next_poll + 1) % self.selections.len(); - } - None - } - - /// Wait until one of the events associated with this [`Selector`] has completed. If the `eventual-fairness` - /// feature flag is enabled, this method is fair and will handle a random event of those that are ready. - pub fn wait(self) -> T { - self.wait_inner(None).unwrap() - } - - /// Wait until one of the events associated with this [`Selector`] has completed or the timeout has expired. If the - /// `eventual-fairness` feature flag is enabled, this method is fair and will handle a random event of those that - /// are ready. - pub fn wait_timeout(self, dur: Duration) -> Result<T, SelectError> { - self.wait_inner(Some(Instant::now() + dur)) - .ok_or(SelectError::Timeout) - } - - /// Wait until one of the events associated with this [`Selector`] has completed or the deadline has been reached. - /// If the `eventual-fairness` feature flag is enabled, this method is fair and will handle a random event of those - /// that are ready. - pub fn wait_deadline(self, deadline: Instant) -> Result<T, SelectError> { - self.wait_inner(Some(deadline)).ok_or(SelectError::Timeout) - } -} diff --git a/vendor/flume/src/signal.rs b/vendor/flume/src/signal.rs deleted file mode 100644 index 89395a3..0000000 --- a/vendor/flume/src/signal.rs +++ /dev/null @@ -1,33 +0,0 @@ -use std::{thread::{self, Thread}, time::Duration, any::Any}; - -pub trait Signal: Send + Sync + 'static { - /// Fire the signal, returning whether it is a stream signal. This is because streams do not - /// acquire a message when woken, so signals must be fired until one that does acquire a message - /// is fired, otherwise a wakeup could be missed, leading to a lost message until one is eagerly - /// grabbed by a receiver. - fn fire(&self) -> bool; - fn as_any(&self) -> &(dyn Any + 'static); - fn as_ptr(&self) -> *const (); -} - -pub struct SyncSignal(Thread); - -impl Default for SyncSignal { - fn default() -> Self { - Self(thread::current()) - } -} - -impl Signal for SyncSignal { - fn fire(&self) -> bool { - self.0.unpark(); - false - } - fn as_any(&self) -> &(dyn Any + 'static) { self } - fn as_ptr(&self) -> *const () { self as *const _ as *const () } -} - -impl SyncSignal { - pub fn wait(&self) { thread::park(); } - pub fn wait_timeout(&self, dur: Duration) { thread::park_timeout(dur); } -} diff --git a/vendor/flume/tests/after.rs b/vendor/flume/tests/after.rs deleted file mode 100644 index 6d25108..0000000 --- a/vendor/flume/tests/after.rs +++ /dev/null @@ -1,339 +0,0 @@ -// //! Tests for the after channel flavor. - -// #[macro_use] -// extern crate crossbeam_channel; -// extern crate crossbeam_utils; -// extern crate rand; - -// use std::sync::atomic::AtomicUsize; -// use std::sync::atomic::Ordering; -// use std::thread; -// use std::time::{Duration, Instant}; - -// use crossbeam_channel::{after, Select, TryRecvError}; -// use crossbeam_utils::thread::scope; - -// fn ms(ms: u64) -> Duration { -// Duration::from_millis(ms) -// } - -// #[test] -// fn fire() { -// let start = Instant::now(); -// let r = after(ms(50)); - -// assert_eq!(r.try_recv(), Err(TryRecvError::Empty)); -// thread::sleep(ms(100)); - -// let fired = r.try_recv().unwrap(); -// assert!(start < fired); -// assert!(fired - start >= ms(50)); - -// let now = Instant::now(); -// assert!(fired < now); -// assert!(now - fired >= ms(50)); - -// assert_eq!(r.try_recv(), Err(TryRecvError::Empty)); - -// select! { -// recv(r) -> _ => panic!(), -// default => {} -// } - -// select! { -// recv(r) -> _ => panic!(), -// recv(after(ms(200))) -> _ => {} -// } -// } - -// #[test] -// fn capacity() { -// const COUNT: usize = 10; - -// for i in 0..COUNT { -// let r = after(ms(i as u64)); -// assert_eq!(r.capacity(), Some(1)); -// } -// } - -// #[test] -// fn len_empty_full() { -// let r = after(ms(50)); - -// assert_eq!(r.len(), 0); -// assert_eq!(r.is_empty(), true); -// assert_eq!(r.is_full(), false); - -// thread::sleep(ms(100)); - -// assert_eq!(r.len(), 1); -// assert_eq!(r.is_empty(), false); -// assert_eq!(r.is_full(), true); - -// r.try_recv().unwrap(); - -// assert_eq!(r.len(), 0); -// assert_eq!(r.is_empty(), true); -// assert_eq!(r.is_full(), false); -// } - -// #[test] -// fn try_recv() { -// let r = after(ms(200)); -// assert!(r.try_recv().is_err()); - -// thread::sleep(ms(100)); -// assert!(r.try_recv().is_err()); - -// thread::sleep(ms(200)); -// assert!(r.try_recv().is_ok()); -// assert!(r.try_recv().is_err()); - -// thread::sleep(ms(200)); -// assert!(r.try_recv().is_err()); -// } - -// #[test] -// fn recv() { -// let start = Instant::now(); -// let r = after(ms(50)); - -// let fired = r.recv().unwrap(); -// assert!(start < fired); -// assert!(fired - start >= ms(50)); - -// let now = Instant::now(); -// assert!(fired < now); -// assert!(now - fired < fired - start); - -// assert_eq!(r.try_recv(), Err(TryRecvError::Empty)); -// } - -// #[test] -// fn recv_timeout() { -// let start = Instant::now(); -// let r = after(ms(200)); - -// assert!(r.recv_timeout(ms(100)).is_err()); -// let now = Instant::now(); -// assert!(now - start >= ms(100)); -// assert!(now - start <= ms(150)); - -// let fired = r.recv_timeout(ms(200)).unwrap(); -// assert!(fired - start >= ms(200)); -// assert!(fired - start <= ms(250)); - -// assert!(r.recv_timeout(ms(200)).is_err()); -// let now = Instant::now(); -// assert!(now - start >= ms(400)); -// assert!(now - start <= ms(450)); - -// assert_eq!(r.try_recv(), Err(TryRecvError::Empty)); -// } - -// #[test] -// fn recv_two() { -// let r1 = after(ms(50)); -// let r2 = after(ms(50)); - -// scope(|scope| { -// scope.spawn(|_| { -// select! { -// recv(r1) -> _ => {} -// recv(r2) -> _ => {} -// } -// }); -// scope.spawn(|_| { -// select! { -// recv(r1) -> _ => {} -// recv(r2) -> _ => {} -// } -// }); -// }) -// .unwrap(); -// } - -// #[test] -// fn recv_race() { -// select! { -// recv(after(ms(50))) -> _ => {} -// recv(after(ms(100))) -> _ => panic!(), -// } - -// select! { -// recv(after(ms(100))) -> _ => panic!(), -// recv(after(ms(50))) -> _ => {} -// } -// } - -// #[test] -// fn stress_default() { -// const COUNT: usize = 10; - -// for _ in 0..COUNT { -// select! { -// recv(after(ms(0))) -> _ => {} -// default => panic!(), -// } -// } - -// for _ in 0..COUNT { -// select! { -// recv(after(ms(100))) -> _ => panic!(), -// default => {} -// } -// } -// } - -// #[test] -// fn select() { -// const THREADS: usize = 4; -// const COUNT: usize = 1000; -// const TIMEOUT_MS: u64 = 100; - -// let v = (0..COUNT) -// .map(|i| after(ms(i as u64 / TIMEOUT_MS / 2))) -// .collect::<Vec<_>>(); -// let hits = AtomicUsize::new(0); - -// scope(|scope| { -// for _ in 0..THREADS { -// scope.spawn(|_| { -// let v: Vec<&_> = v.iter().collect(); - -// loop { -// let timeout = after(ms(TIMEOUT_MS)); -// let mut sel = Select::new(); -// for r in &v { -// sel.recv(r); -// } -// let oper_timeout = sel.recv(&timeout); - -// let oper = sel.select(); -// match oper.index() { -// i if i == oper_timeout => { -// oper.recv(&timeout).unwrap(); -// break; -// } -// i => { -// oper.recv(&v[i]).unwrap(); -// hits.fetch_add(1, Ordering::SeqCst); -// } -// } -// } -// }); -// } -// }) -// .unwrap(); - -// assert_eq!(hits.load(Ordering::SeqCst), COUNT); -// } - -// #[test] -// fn ready() { -// const THREADS: usize = 4; -// const COUNT: usize = 1000; -// const TIMEOUT_MS: u64 = 100; - -// let v = (0..COUNT) -// .map(|i| after(ms(i as u64 / TIMEOUT_MS / 2))) -// .collect::<Vec<_>>(); -// let hits = AtomicUsize::new(0); - -// scope(|scope| { -// for _ in 0..THREADS { -// scope.spawn(|_| { -// let v: Vec<&_> = v.iter().collect(); - -// loop { -// let timeout = after(ms(TIMEOUT_MS)); -// let mut sel = Select::new(); -// for r in &v { -// sel.recv(r); -// } -// let oper_timeout = sel.recv(&timeout); - -// loop { -// let i = sel.ready(); -// if i == oper_timeout { -// timeout.try_recv().unwrap(); -// return; -// } else if v[i].try_recv().is_ok() { -// hits.fetch_add(1, Ordering::SeqCst); -// break; -// } -// } -// } -// }); -// } -// }) -// .unwrap(); - -// assert_eq!(hits.load(Ordering::SeqCst), COUNT); -// } - -// #[test] -// fn stress_clone() { -// const RUNS: usize = 1000; -// const THREADS: usize = 10; -// const COUNT: usize = 50; - -// for i in 0..RUNS { -// let r = after(ms(i as u64)); - -// scope(|scope| { -// for _ in 0..THREADS { -// scope.spawn(|_| { -// let r = r.clone(); -// let _ = r.try_recv(); - -// for _ in 0..COUNT { -// drop(r.clone()); -// thread::yield_now(); -// } -// }); -// } -// }) -// .unwrap(); -// } -// } - -// #[test] -// fn fairness() { -// const COUNT: usize = 1000; - -// for &dur in &[0, 1] { -// let mut hits = [0usize; 2]; - -// for _ in 0..COUNT { -// select! { -// recv(after(ms(dur))) -> _ => hits[0] += 1, -// recv(after(ms(dur))) -> _ => hits[1] += 1, -// } -// } - -// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2)); -// } -// } - -// #[test] -// fn fairness_duplicates() { -// const COUNT: usize = 1000; - -// for &dur in &[0, 1] { -// let mut hits = [0usize; 5]; - -// for _ in 0..COUNT { -// let r = after(ms(dur)); -// select! { -// recv(r) -> _ => hits[0] += 1, -// recv(r) -> _ => hits[1] += 1, -// recv(r) -> _ => hits[2] += 1, -// recv(r) -> _ => hits[3] += 1, -// recv(r) -> _ => hits[4] += 1, -// } -// } - -// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2)); -// } -// } diff --git a/vendor/flume/tests/array.rs b/vendor/flume/tests/array.rs deleted file mode 100644 index a72bbe3..0000000 --- a/vendor/flume/tests/array.rs +++ /dev/null @@ -1,657 +0,0 @@ -//! Tests for the array channel flavor. - -extern crate crossbeam_utils; -extern crate rand; - -use std::any::Any; -use std::sync::atomic::AtomicUsize; -use std::sync::atomic::Ordering; -use std::thread; -use std::time::Duration; - -use flume::{bounded, Receiver}; -use flume::{RecvError, RecvTimeoutError, TryRecvError}; -use flume::{SendError, SendTimeoutError, TrySendError}; -use crossbeam_utils::thread::scope; -use rand::{thread_rng, Rng}; - -fn ms(ms: u64) -> Duration { - Duration::from_millis(ms) -} - -#[test] -fn smoke() { - let (s, r) = bounded(1); - s.send(7).unwrap(); - assert_eq!(r.try_recv(), Ok(7)); - - s.send(8).unwrap(); - assert_eq!(r.recv(), Ok(8)); - - assert_eq!(r.try_recv(), Err(TryRecvError::Empty)); - assert_eq!(r.recv_timeout(ms(1000)), Err(RecvTimeoutError::Timeout)); -} - -#[test] -fn capacity() { - for i in 1..10 { - let (s, r) = bounded::<()>(i); - assert_eq!(s.capacity(), Some(i)); - assert_eq!(r.capacity(), Some(i)); - } -} - -#[test] -fn len_empty_full() { - let (s, r) = bounded(2); - - assert_eq!(s.len(), 0); - assert_eq!(s.is_empty(), true); - assert_eq!(s.is_full(), false); - assert_eq!(r.len(), 0); - assert_eq!(r.is_empty(), true); - assert_eq!(r.is_full(), false); - - s.send(()).unwrap(); - - assert_eq!(s.len(), 1); - assert_eq!(s.is_empty(), false); - assert_eq!(s.is_full(), false); - assert_eq!(r.len(), 1); - assert_eq!(r.is_empty(), false); - assert_eq!(r.is_full(), false); - - s.send(()).unwrap(); - - assert_eq!(s.len(), 2); - assert_eq!(s.is_empty(), false); - assert_eq!(s.is_full(), true); - assert_eq!(r.len(), 2); - assert_eq!(r.is_empty(), false); - assert_eq!(r.is_full(), true); - - r.recv().unwrap(); - - assert_eq!(s.len(), 1); - assert_eq!(s.is_empty(), false); - assert_eq!(s.is_full(), false); - assert_eq!(r.len(), 1); - assert_eq!(r.is_empty(), false); - assert_eq!(r.is_full(), false); -} - -#[test] -fn try_recv() { - let (s, r) = bounded(100); - - scope(|scope| { - scope.spawn(move |_| { - assert_eq!(r.try_recv(), Err(TryRecvError::Empty)); - thread::sleep(ms(1500)); - assert_eq!(r.try_recv(), Ok(7)); - thread::sleep(ms(500)); - assert_eq!(r.try_recv(), Err(TryRecvError::Disconnected)); - }); - scope.spawn(move |_| { - thread::sleep(ms(1000)); - s.send(7).unwrap(); - }); - }) - .unwrap(); -} - -#[test] -fn recv() { - let (s, r) = bounded(100); - - scope(|scope| { - scope.spawn(move |_| { - assert_eq!(r.recv(), Ok(7)); - thread::sleep(ms(1000)); - assert_eq!(r.recv(), Ok(8)); - thread::sleep(ms(1000)); - assert_eq!(r.recv(), Ok(9)); - assert!(r.recv().is_err()); - }); - scope.spawn(move |_| { - thread::sleep(ms(1500)); - s.send(7).unwrap(); - s.send(8).unwrap(); - s.send(9).unwrap(); - }); - }) - .unwrap(); -} - -#[test] -fn recv_timeout() { - let (s, r) = bounded::<i32>(100); - - scope(|scope| { - scope.spawn(move |_| { - assert_eq!(r.recv_timeout(ms(1000)), Err(RecvTimeoutError::Timeout)); - assert_eq!(r.recv_timeout(ms(1000)), Ok(7)); - assert_eq!( - r.recv_timeout(ms(1000)), - Err(RecvTimeoutError::Disconnected) - ); - }); - scope.spawn(move |_| { - thread::sleep(ms(1500)); - s.send(7).unwrap(); - }); - }) - .unwrap(); -} - -#[test] -fn try_send() { - let (s, r) = bounded(1); - - scope(|scope| { - scope.spawn(move |_| { - assert_eq!(s.try_send(1), Ok(())); - assert_eq!(s.try_send(2), Err(TrySendError::Full(2))); - thread::sleep(ms(1500)); - assert_eq!(s.try_send(3), Ok(())); - thread::sleep(ms(500)); - assert_eq!(s.try_send(4), Err(TrySendError::Disconnected(4))); - }); - scope.spawn(move |_| { - thread::sleep(ms(1000)); - assert_eq!(r.try_recv(), Ok(1)); - assert_eq!(r.try_recv(), Err(TryRecvError::Empty)); - assert_eq!(r.recv(), Ok(3)); - }); - }) - .unwrap(); -} - -#[test] -fn send() { - let (s, r) = bounded(1); - - scope(|scope| { - scope.spawn(|_| { - s.send(7).unwrap(); - thread::sleep(ms(1000)); - s.send(8).unwrap(); - thread::sleep(ms(1000)); - s.send(9).unwrap(); - thread::sleep(ms(1000)); - s.send(10).unwrap(); - }); - scope.spawn(|_| { - thread::sleep(ms(1500)); - assert_eq!(r.recv(), Ok(7)); - assert_eq!(r.recv(), Ok(8)); - assert_eq!(r.recv(), Ok(9)); - }); - }) - .unwrap(); -} - -#[test] -fn send_timeout() { - let (s, r) = bounded(2); - - scope(|scope| { - scope.spawn(move |_| { - assert_eq!(s.send_timeout(1, ms(1000)), Ok(())); - assert_eq!(s.send_timeout(2, ms(1000)), Ok(())); - assert_eq!( - s.send_timeout(3, ms(500)), - Err(SendTimeoutError::Timeout(3)) - ); - thread::sleep(ms(1000)); - assert_eq!(s.send_timeout(4, ms(1000)), Ok(())); - thread::sleep(ms(1000)); - assert_eq!(s.send(5), Err(SendError(5))); - }); - scope.spawn(move |_| { - thread::sleep(ms(1000)); - assert_eq!(r.recv(), Ok(1)); - thread::sleep(ms(1000)); - assert_eq!(r.recv(), Ok(2)); - assert_eq!(r.recv(), Ok(4)); - }); - }) - .unwrap(); -} - -#[test] -fn send_after_disconnect() { - let (s, r) = bounded(100); - - s.send(1).unwrap(); - s.send(2).unwrap(); - s.send(3).unwrap(); - - drop(r); - - assert_eq!(s.send(4), Err(SendError(4))); - assert_eq!(s.try_send(5), Err(TrySendError::Disconnected(5))); - assert_eq!( - s.send_timeout(6, ms(500)), - Err(SendTimeoutError::Disconnected(6)) - ); -} - -#[test] -fn recv_after_disconnect() { - let (s, r) = bounded(100); - - s.send(1).unwrap(); - s.send(2).unwrap(); - s.send(3).unwrap(); - - drop(s); - - assert_eq!(r.recv(), Ok(1)); - assert_eq!(r.recv(), Ok(2)); - assert_eq!(r.recv(), Ok(3)); - assert!(r.recv().is_err()); -} - -#[test] -fn len() { - const COUNT: usize = 25_000; - const CAP: usize = 1000; - - let (s, r) = bounded(CAP); - - assert_eq!(s.len(), 0); - assert_eq!(r.len(), 0); - - for _ in 0..CAP / 10 { - for i in 0..50 { - s.send(i).unwrap(); - assert_eq!(s.len(), i + 1); - } - - for i in 0..50 { - r.recv().unwrap(); - assert_eq!(r.len(), 50 - i - 1); - } - } - - assert_eq!(s.len(), 0); - assert_eq!(r.len(), 0); - - for i in 0..CAP { - s.send(i).unwrap(); - assert_eq!(s.len(), i + 1); - } - - for _ in 0..CAP { - r.recv().unwrap(); - } - - assert_eq!(s.len(), 0); - assert_eq!(r.len(), 0); - - scope(|scope| { - scope.spawn(|_| { - for i in 0..COUNT { - assert_eq!(r.recv(), Ok(i)); - let len = r.len(); - assert!(len <= CAP); - } - }); - - scope.spawn(|_| { - for i in 0..COUNT { - s.send(i).unwrap(); - let len = s.len(); - assert!(len <= CAP); - } - }); - }) - .unwrap(); - - assert_eq!(s.len(), 0); - assert_eq!(r.len(), 0); -} - -#[test] -fn disconnect_wakes_sender() { - let (s, r) = bounded(1); - - scope(|scope| { - scope.spawn(move |_| { - assert_eq!(s.send(()), Ok(())); - assert_eq!(s.send(()), Err(SendError(()))); - }); - scope.spawn(move |_| { - thread::sleep(ms(1000)); - drop(r); - }); - }) - .unwrap(); -} - -#[test] -fn disconnect_wakes_receiver() { - let (s, r) = bounded::<()>(1); - - scope(|scope| { - scope.spawn(move |_| { - assert!(r.recv().is_err()); - }); - scope.spawn(move |_| { - thread::sleep(ms(1000)); - drop(s); - }); - }) - .unwrap(); -} - -#[test] -fn spsc() { - const COUNT: usize = 100_000; - - let (s, r) = bounded(3); - - scope(|scope| { - scope.spawn(move |_| { - for i in 0..COUNT { - assert_eq!(r.recv(), Ok(i)); - } - assert!(r.recv().is_err()); - }); - scope.spawn(move |_| { - for i in 0..COUNT { - s.send(i).unwrap(); - } - }); - }) - .unwrap(); -} - -#[test] -fn mpmc() { - const COUNT: usize = 25_000; - const THREADS: usize = 4; - - let (s, r) = bounded::<usize>(3); - let v = (0..COUNT).map(|_| AtomicUsize::new(0)).collect::<Vec<_>>(); - - scope(|scope| { - for _ in 0..THREADS { - scope.spawn(|_| { - for _ in 0..COUNT { - let n = r.recv().unwrap(); - v[n].fetch_add(1, Ordering::SeqCst); - } - }); - } - for _ in 0..THREADS { - scope.spawn(|_| { - for i in 0..COUNT { - s.send(i).unwrap(); - } - }); - } - }) - .unwrap(); - - for c in v { - assert_eq!(c.load(Ordering::SeqCst), THREADS); - } -} - -#[test] -fn stress_oneshot() { - const COUNT: usize = 10_000; - - for _ in 0..COUNT { - let (s, r) = bounded(1); - - scope(|scope| { - scope.spawn(|_| r.recv().unwrap()); - scope.spawn(|_| s.send(0).unwrap()); - }) - .unwrap(); - } -} - -#[test] -fn stress_iter() { - const COUNT: usize = 100_000; - - let (request_s, request_r) = bounded(1); - let (response_s, response_r) = bounded(1); - - scope(|scope| { - scope.spawn(move |_| { - let mut count = 0; - loop { - for x in response_r.try_iter() { - count += x; - if count == COUNT { - return; - } - } - request_s.send(()).unwrap(); - } - }); - - for _ in request_r.iter() { - if response_s.send(1).is_err() { - break; - } - } - }) - .unwrap(); -} - -#[test] -fn stress_timeout_two_threads() { - const COUNT: usize = 100; - - let (s, r) = bounded(2); - - scope(|scope| { - scope.spawn(|_| { - for i in 0..COUNT { - if i % 2 == 0 { - thread::sleep(ms(50)); - } - loop { - if let Ok(()) = s.send_timeout(i, ms(10)) { - break; - } - } - } - }); - - scope.spawn(|_| { - for i in 0..COUNT { - if i % 2 == 0 { - thread::sleep(ms(50)); - } - loop { - if let Ok(x) = r.recv_timeout(ms(10)) { - assert_eq!(x, i); - break; - } - } - } - }); - }) - .unwrap(); -} - -#[test] -fn drops() { - const RUNS: usize = 100; - - static DROPS: AtomicUsize = AtomicUsize::new(0); - - #[derive(Debug, PartialEq)] - struct DropCounter; - - impl Drop for DropCounter { - fn drop(&mut self) { - DROPS.fetch_add(1, Ordering::SeqCst); - } - } - - let mut rng = thread_rng(); - - for _ in 0..RUNS { - let steps = rng.gen_range(0..10_000); - let additional = rng.gen_range(0..50); - - DROPS.store(0, Ordering::SeqCst); - let (s, r) = bounded::<DropCounter>(50); - - scope(|scope| { - scope.spawn(|_| { - for _ in 0..steps { - r.recv().unwrap(); - } - }); - - scope.spawn(|_| { - for _ in 0..steps { - s.send(DropCounter).unwrap(); - } - }); - }) - .unwrap(); - - for _ in 0..additional { - s.send(DropCounter).unwrap(); - } - - assert_eq!(DROPS.load(Ordering::SeqCst), steps); - drop(s); - drop(r); - assert_eq!(DROPS.load(Ordering::SeqCst), steps + additional); - } -} - -#[test] -fn linearizable() { - const COUNT: usize = 25_000; - const THREADS: usize = 4; - - let (s, r) = bounded(THREADS); - - scope(|scope| { - for _ in 0..THREADS { - scope.spawn(|_| { - for _ in 0..COUNT { - s.send(0).unwrap(); - r.try_recv().unwrap(); - } - }); - } - }) - .unwrap(); -} - -// #[test] -// fn fairness() { -// const COUNT: usize = 10_000; - -// let (s1, r1) = bounded::<()>(COUNT); -// let (s2, r2) = bounded::<()>(COUNT); - -// for _ in 0..COUNT { -// s1.send(()).unwrap(); -// s2.send(()).unwrap(); -// } - -// let mut hits = [0usize; 2]; -// for _ in 0..COUNT { -// select! { -// recv(r1) -> _ => hits[0] += 1, -// recv(r2) -> _ => hits[1] += 1, -// } -// } -// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2)); -// } - -// #[test] -// fn fairness_duplicates() { -// const COUNT: usize = 10_000; - -// let (s, r) = bounded::<()>(COUNT); - -// for _ in 0..COUNT { -// s.send(()).unwrap(); -// } - -// let mut hits = [0usize; 5]; -// for _ in 0..COUNT { -// select! { -// recv(r) -> _ => hits[0] += 1, -// recv(r) -> _ => hits[1] += 1, -// recv(r) -> _ => hits[2] += 1, -// recv(r) -> _ => hits[3] += 1, -// recv(r) -> _ => hits[4] += 1, -// } -// } -// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2)); -// } - -// #[test] -// fn recv_in_send() { -// let (s, _r) = bounded(1); -// s.send(()).unwrap(); - -// #[allow(unreachable_code)] -// { -// select! { -// send(s, panic!()) -> _ => panic!(), -// default => {} -// } -// } - -// let (s, r) = bounded(2); -// s.send(()).unwrap(); - -// select! { -// send(s, assert_eq!(r.recv(), Ok(()))) -> _ => {} -// } -// } - -#[test] -fn channel_through_channel() { - const COUNT: usize = 1000; - - type T = Box<dyn Any + Send>; - - let (s, r) = bounded::<T>(1); - - scope(|scope| { - scope.spawn(move |_| { - let mut s = s; - - for _ in 0..COUNT { - let (new_s, new_r) = bounded(1); - let new_r: T = Box::new(Some(new_r)); - - s.send(new_r).unwrap(); - s = new_s; - } - }); - - scope.spawn(move |_| { - let mut r = r; - - for _ in 0..COUNT { - r = r - .recv() - .unwrap() - .downcast_mut::<Option<Receiver<T>>>() - .unwrap() - .take() - .unwrap() - } - }); - }) - .unwrap(); -} diff --git a/vendor/flume/tests/async.rs b/vendor/flume/tests/async.rs deleted file mode 100644 index 6c2c7f2..0000000 --- a/vendor/flume/tests/async.rs +++ /dev/null @@ -1,276 +0,0 @@ -#[cfg(feature = "async")] -use { - flume::*, - futures::{stream::FuturesUnordered, StreamExt, TryFutureExt, Future}, - futures::task::{Context, Waker, Poll}, - async_std::prelude::FutureExt, - std::{time::Duration, sync::{atomic::{AtomicUsize, Ordering}, Arc}}, -}; - -#[cfg(feature = "async")] -#[test] -fn r#async_recv() { - let (tx, rx) = unbounded(); - - let t = std::thread::spawn(move || { - std::thread::sleep(std::time::Duration::from_millis(250)); - tx.send(42u32).unwrap(); - }); - - async_std::task::block_on(async { - assert_eq!(rx.recv_async().await.unwrap(), 42); - }); - - t.join().unwrap(); -} - -#[cfg(feature = "async")] -#[test] -fn r#async_send() { - let (tx, rx) = bounded(1); - - let t = std::thread::spawn(move || { - std::thread::sleep(std::time::Duration::from_millis(250)); - assert_eq!(rx.recv(), Ok(42)); - }); - - async_std::task::block_on(async { - tx.send_async(42u32).await.unwrap(); - }); - - t.join().unwrap(); -} - -#[cfg(feature = "async")] -#[test] -fn r#async_recv_disconnect() { - let (tx, rx) = bounded::<i32>(0); - - let t = std::thread::spawn(move || { - std::thread::sleep(std::time::Duration::from_millis(250)); - drop(tx) - }); - - async_std::task::block_on(async { - assert_eq!(rx.recv_async().await, Err(RecvError::Disconnected)); - }); - - t.join().unwrap(); -} - -#[cfg(feature = "async")] -#[test] -fn r#async_send_disconnect() { - let (tx, rx) = bounded(0); - - let t = std::thread::spawn(move || { - std::thread::sleep(std::time::Duration::from_millis(250)); - drop(rx) - }); - - async_std::task::block_on(async { - assert_eq!(tx.send_async(42u32).await, Err(SendError(42))); - }); - - t.join().unwrap(); -} - -#[cfg(feature = "async")] -#[test] -fn r#async_recv_drop_recv() { - let (tx, rx) = bounded::<i32>(10); - - let recv_fut = rx.recv_async(); - - async_std::task::block_on(async { - let res = async_std::future::timeout(std::time::Duration::from_millis(500), rx.recv_async()).await; - assert!(res.is_err()); - }); - - let rx2 = rx.clone(); - let t = std::thread::spawn(move || { - async_std::task::block_on(async { - rx2.recv_async().await - }) - }); - - std::thread::sleep(std::time::Duration::from_millis(500)); - - tx.send(42).unwrap(); - - drop(recv_fut); - - assert_eq!(t.join().unwrap(), Ok(42)) -} - -#[cfg(feature = "async")] -#[async_std::test] -async fn r#async_send_1_million_no_drop_or_reorder() { - #[derive(Debug)] - enum Message { - Increment { - old: u64, - }, - ReturnCount, - } - - let (tx, rx) = unbounded(); - - let t = async_std::task::spawn(async move { - let mut count = 0u64; - - while let Ok(Message::Increment { old }) = rx.recv_async().await { - assert_eq!(old, count); - count += 1; - } - - count - }); - - for next in 0..1_000_000 { - tx.send(Message::Increment { old: next }).unwrap(); - } - - tx.send(Message::ReturnCount).unwrap(); - - let count = t.await; - assert_eq!(count, 1_000_000) -} - -#[cfg(feature = "async")] -#[async_std::test] -async fn parallel_async_receivers() { - let (tx, rx) = flume::unbounded(); - let send_fut = async move { - let n_sends: usize = 100000; - for _ in 0..n_sends { - tx.send_async(()).await.unwrap(); - } - }; - - async_std::task::spawn( - send_fut - .timeout(Duration::from_secs(5)) - .map_err(|_| panic!("Send timed out!")) - ); - - let mut futures_unordered = (0..250) - .map(|_| async { - while let Ok(()) = rx.recv_async().await - /* rx.recv() is OK */ - {} - }) - .collect::<FuturesUnordered<_>>(); - - let recv_fut = async { - while futures_unordered.next().await.is_some() {} - }; - - recv_fut - .timeout(Duration::from_secs(5)) - .map_err(|_| panic!("Receive timed out!")) - .await - .unwrap(); - - println!("recv end"); -} - -#[cfg(feature = "async")] -#[test] -fn change_waker() { - let (tx, rx) = flume::bounded(1); - tx.send(()).unwrap(); - - struct DebugWaker(Arc<AtomicUsize>, Waker); - - impl DebugWaker { - fn new() -> Self { - let woken = Arc::new(AtomicUsize::new(0)); - let woken_cloned = woken.clone(); - let waker = waker_fn::waker_fn(move || { - woken.fetch_add(1, Ordering::SeqCst); - }); - DebugWaker(woken_cloned, waker) - } - - fn woken(&self) -> usize { - self.0.load(Ordering::SeqCst) - } - - fn ctx(&self) -> Context { - Context::from_waker(&self.1) - } - } - - // Check that the waker is correctly updated when sending tasks change their wakers - { - let send_fut = tx.send_async(()); - futures::pin_mut!(send_fut); - - let (waker1, waker2) = (DebugWaker::new(), DebugWaker::new()); - - // Set the waker to waker1 - assert_eq!(send_fut.as_mut().poll(&mut waker1.ctx()), Poll::Pending); - - // Change the waker to waker2 - assert_eq!(send_fut.poll(&mut waker2.ctx()), Poll::Pending); - - // Wake the future - rx.recv().unwrap(); - - // Check that waker2 was woken and waker1 was not - assert_eq!(waker1.woken(), 0); - assert_eq!(waker2.woken(), 1); - } - - // Check that the waker is correctly updated when receiving tasks change their wakers - { - rx.recv().unwrap(); - let recv_fut = rx.recv_async(); - futures::pin_mut!(recv_fut); - - let (waker1, waker2) = (DebugWaker::new(), DebugWaker::new()); - - // Set the waker to waker1 - assert_eq!(recv_fut.as_mut().poll(&mut waker1.ctx()), Poll::Pending); - - // Change the waker to waker2 - assert_eq!(recv_fut.poll(&mut waker2.ctx()), Poll::Pending); - - // Wake the future - tx.send(()).unwrap(); - - // Check that waker2 was woken and waker1 was not - assert_eq!(waker1.woken(), 0); - assert_eq!(waker2.woken(), 1); - } -} - -#[cfg(feature = "async")] -#[test] -fn spsc_single_threaded_value_ordering() { - async fn test() { - let (tx, rx) = flume::bounded(4); - tokio::select! { - _ = producer(tx) => {}, - _ = consumer(rx) => {}, - } - } - - async fn producer(tx: flume::Sender<usize>) { - for i in 0..100 { - tx.send_async(i).await.unwrap(); - } - } - - async fn consumer(rx: flume::Receiver<usize>) { - let mut expected = 0; - while let Ok(value) = rx.recv_async().await { - assert_eq!(value, expected); - expected += 1; - } - } - - let rt = tokio::runtime::Builder::new_current_thread().build().unwrap(); - rt.block_on(test()); -} diff --git a/vendor/flume/tests/basic.rs b/vendor/flume/tests/basic.rs deleted file mode 100644 index b937436..0000000 --- a/vendor/flume/tests/basic.rs +++ /dev/null @@ -1,428 +0,0 @@ -use std::time::{Instant, Duration}; -use flume::*; - -#[test] -fn send_recv() { - let (tx, rx) = unbounded(); - for i in 0..1000 { tx.send(i).unwrap(); } - for i in 0..1000 { assert_eq!(rx.try_recv().unwrap(), i); } - assert!(rx.try_recv().is_err()); -} - -#[test] -fn iter() { - let (tx, rx) = unbounded(); - for i in 0..1000 { tx.send(i).unwrap(); } - drop(tx); - assert_eq!(rx.iter().sum::<u32>(), (0..1000).sum()); -} - -#[test] -fn try_iter() { - let (tx, rx) = unbounded(); - for i in 0..1000 { tx.send(i).unwrap(); } - assert_eq!(rx.try_iter().sum::<u32>(), (0..1000).sum()); -} - -#[test] -fn iter_threaded() { - let (tx, rx) = unbounded(); - for i in 0..1000 { - let tx = tx.clone(); - std::thread::spawn(move || tx.send(i).unwrap()); - } - drop(tx); - assert_eq!(rx.iter().sum::<u32>(), (0..1000).sum()); -} - -#[cfg_attr(any(target_os = "macos", windows), ignore)] // FIXME #41 -#[test] -fn send_timeout() { - let dur = Duration::from_millis(350); - let max_error = Duration::from_millis(5); - let dur_min = dur.checked_sub(max_error).unwrap(); - let dur_max = dur.checked_add(max_error).unwrap(); - - let (tx, rx) = bounded(1); - - assert!(tx.send_timeout(42, dur).is_ok()); - - let then = Instant::now(); - assert!(tx.send_timeout(43, dur).is_err()); - let now = Instant::now(); - - let this = now.duration_since(then); - if !(dur_min < this && this < dur_max) { - panic!("timeout exceeded: {:?}", this); - } - - assert_eq!(rx.drain().count(), 1); - - drop(rx); - - assert!(tx.send_timeout(42, Duration::from_millis(350)).is_err()); -} - -#[cfg_attr(any(target_os = "macos", windows), ignore)] // FIXME #41 -#[test] -fn recv_timeout() { - let dur = Duration::from_millis(350); - let max_error = Duration::from_millis(5); - let dur_min = dur.checked_sub(max_error).unwrap(); - let dur_max = dur.checked_add(max_error).unwrap(); - - let (tx, rx) = unbounded(); - let then = Instant::now(); - assert!(rx.recv_timeout(dur).is_err()); - let now = Instant::now(); - - let this = now.duration_since(then); - if !(dur_min < this && this < dur_max) { - panic!("timeout exceeded: {:?}", this); - } - - tx.send(42).unwrap(); - assert_eq!(rx.recv_timeout(dur), Ok(42)); - assert!(Instant::now().duration_since(now) < max_error); -} - -#[cfg_attr(any(target_os = "macos", windows), ignore)] // FIXME #41 -#[test] -fn recv_deadline() { - let dur = Duration::from_millis(350); - let max_error = Duration::from_millis(5); - let dur_min = dur.checked_sub(max_error).unwrap(); - let dur_max = dur.checked_add(max_error).unwrap(); - - let (tx, rx) = unbounded(); - let then = Instant::now(); - assert!(rx.recv_deadline(then.checked_add(dur).unwrap()).is_err()); - let now = Instant::now(); - - let this = now.duration_since(then); - if !(dur_min < this && this < dur_max) { - panic!("timeout exceeded: {:?}", this); - } - - tx.send(42).unwrap(); - assert_eq!(rx.recv_deadline(now.checked_add(dur).unwrap()), Ok(42)); - assert!(Instant::now().duration_since(now) < max_error); -} - -#[test] -fn recv_timeout_missed_send() { - let (tx, rx) = bounded(10); - - assert!(rx.recv_timeout(Duration::from_millis(100)).is_err()); - - tx.send(42).unwrap(); - - assert_eq!(rx.recv(), Ok(42)); -} - -#[test] -fn disconnect_tx() { - let (tx, rx) = unbounded::<()>(); - drop(tx); - assert!(rx.recv().is_err()); -} - -#[test] -fn disconnect_rx() { - let (tx, rx) = unbounded(); - drop(rx); - assert!(tx.send(0).is_err()); -} - -#[test] -fn drain() { - let (tx, rx) = unbounded(); - - for i in 0..100 { - tx.send(i).unwrap(); - } - - assert_eq!(rx.drain().sum::<u32>(), (0..100).sum()); - - for i in 0..100 { - tx.send(i).unwrap(); - } - - for i in 0..100 { - tx.send(i).unwrap(); - } - - rx.recv().unwrap(); - - (1u32..100).chain(0..100).zip(rx).for_each(|(l, r)| assert_eq!(l, r)); -} - -#[test] -fn try_send() { - let (tx, rx) = bounded(5); - - for i in 0..5 { - tx.try_send(i).unwrap(); - } - - assert!(tx.try_send(42).is_err()); - - assert_eq!(rx.recv(), Ok(0)); - - assert_eq!(tx.try_send(42), Ok(())); - - assert_eq!(rx.recv(), Ok(1)); - drop(rx); - - assert!(tx.try_send(42).is_err()); -} - -#[test] -fn send_bounded() { - let (tx, rx) = bounded(5); - - for _ in 0..5 { - tx.send(42).unwrap(); - } - - let _ = rx.recv().unwrap(); - - tx.send(42).unwrap(); - - assert!(tx.try_send(42).is_err()); - - rx.drain(); - - let mut ts = Vec::new(); - for _ in 0..100 { - let tx = tx.clone(); - ts.push(std::thread::spawn(move || { - for i in 0..10000 { - tx.send(i).unwrap(); - } - })); - } - - drop(tx); - - assert_eq!(rx.iter().sum::<u64>(), (0..10000).sum::<u64>() * 100); - - for t in ts { - t.join().unwrap(); - } - - assert!(rx.recv().is_err()); -} - -#[test] -fn rendezvous() { - let (tx, rx) = bounded(0); - - for i in 0..5 { - let tx = tx.clone(); - let t = std::thread::spawn(move || { - assert!(tx.try_send(()).is_err()); - - let then = Instant::now(); - tx.send(()).unwrap(); - let now = Instant::now(); - - assert!(now.duration_since(then) > Duration::from_millis(100), "iter = {}", i); - }); - - std::thread::sleep(Duration::from_millis(1000)); - rx.recv().unwrap(); - - t.join().unwrap(); - } -} - -#[test] -fn hydra() { - let thread_num = 32; - let msg_num = 1000; - - let (main_tx, main_rx) = unbounded::<()>(); - - let mut txs = Vec::new(); - for _ in 0..thread_num { - let main_tx = main_tx.clone(); - let (tx, rx) = unbounded(); - txs.push(tx); - - std::thread::spawn(move || { - for msg in rx.iter() { - main_tx.send(msg).unwrap(); - } - }); - } - - drop(main_tx); - - for _ in 0..10 { - for tx in &txs { - for _ in 0..msg_num { - tx.send(Default::default()).unwrap(); - } - } - - for _ in 0..thread_num { - for _ in 0..msg_num { - main_rx.recv().unwrap(); - } - } - } - - drop(txs); - assert!(main_rx.recv().is_err()); -} - -#[test] -fn robin() { - let thread_num = 32; - let msg_num = 10; - - let (mut main_tx, main_rx) = bounded::<()>(1); - - for _ in 0..thread_num { - let (mut tx, rx) = bounded(100); - std::mem::swap(&mut tx, &mut main_tx); - - std::thread::spawn(move || { - for msg in rx.iter() { - tx.send(msg).unwrap(); - } - }); - } - - for _ in 0..10 { - let main_tx = main_tx.clone(); - std::thread::spawn(move || { - for _ in 0..msg_num { - main_tx.send(Default::default()).unwrap(); - } - }); - - for _ in 0..msg_num { - main_rx.recv().unwrap(); - } - } -} - -#[cfg(feature = "select")] -#[test] -fn select_general() { - #[derive(Debug, PartialEq)] - struct Foo(usize); - - let (tx0, rx0) = bounded(1); - let (tx1, rx1) = unbounded(); - - for (i, t) in vec![tx0.clone(), tx1].into_iter().enumerate() { - std::thread::spawn(move || { - std::thread::sleep(std::time::Duration::from_millis(250)); - let _ = t.send(Foo(i)); - }); - } - - let x = Selector::new() - .recv(&rx0, |x| x) - .recv(&rx1, |x| x) - .wait() - .unwrap(); - - if x == Foo(0) { - assert!(rx1.recv().unwrap() == Foo(1)); - } else { - assert!(rx0.recv().unwrap() == Foo(0)); - } - - tx0.send(Foo(42)).unwrap(); - - let t = std::thread::spawn(move || { - std::thread::sleep(std::time::Duration::from_millis(100)); - assert_eq!(rx0.recv().unwrap(), Foo(42)); - assert_eq!(rx0.recv().unwrap(), Foo(43)); - - }); - - Selector::new() - .send(&tx0, Foo(43), |x| x) - .wait() - .unwrap(); - - t.join().unwrap(); -} - -struct MessageWithoutDebug(u32); - -#[test] -// This is a 'does it build' test, to make sure that the error types can turn -// into a std::error::Error without requiring the payload (which is not used -// there) to impl Debug. -fn std_error_without_debug() { - let (tx, rx) = unbounded::<MessageWithoutDebug>(); - - match tx.send(MessageWithoutDebug(1)) { - Ok(_) => {} - Err(e) => { - let _std_err: &dyn std::error::Error = &e; - } - } - - match rx.recv() { - Ok(_) => {} - Err(e) => { - let _std_err: &dyn std::error::Error = &e; - } - } - - match tx.try_send(MessageWithoutDebug(2)) { - Ok(_) => {} - Err(e) => { - let _std_err: &dyn std::error::Error = &e; - } - } - - match rx.try_recv() { - Ok(_) => {} - Err(e) => { - let _std_err: &dyn std::error::Error = &e; - } - } - - match tx.send_timeout(MessageWithoutDebug(3), Duration::from_secs(1000000)) { - Ok(_) => {} - Err(e) => { - let _std_err: &dyn std::error::Error = &e; - } - } - - match rx.recv_timeout(Duration::from_secs(10000000)) { - Ok(_) => {} - Err(e) => { - let _std_err: &dyn std::error::Error = &e; - } - } -} - -#[test] -fn weak_close() { - let (tx, rx) = unbounded::<()>(); - let weak = tx.downgrade(); - drop(tx); - assert!(weak.upgrade().is_none()); - assert!(rx.is_disconnected()); - assert!(rx.try_recv().is_err()); -} - -#[test] -fn weak_upgrade() { - let (tx, rx) = unbounded(); - let weak = tx.downgrade(); - let tx2 = weak.upgrade().unwrap(); - drop(tx); - assert!(!rx.is_disconnected()); - tx2.send(()).unwrap(); - assert!(rx.try_recv().is_ok()); -} diff --git a/vendor/flume/tests/check_same_channel.rs b/vendor/flume/tests/check_same_channel.rs deleted file mode 100644 index edb82c3..0000000 --- a/vendor/flume/tests/check_same_channel.rs +++ /dev/null @@ -1,57 +0,0 @@ -#[test] -fn same_sender() { - let (tx1, _rx) = flume::unbounded::<()>(); - let tx2 = tx1.clone(); - - assert!(tx1.same_channel(&tx2)); - - let (tx3, _rx) = flume::unbounded::<()>(); - - assert!(!tx1.same_channel(&tx3)); - assert!(!tx2.same_channel(&tx3)); -} - -#[test] -fn same_receiver() { - let (_tx, rx1) = flume::unbounded::<()>(); - let rx2 = rx1.clone(); - - assert!(rx1.same_channel(&rx2)); - - let (_tx, rx3) = flume::unbounded::<()>(); - - assert!(!rx1.same_channel(&rx3)); - assert!(!rx2.same_channel(&rx3)); -} - -#[cfg(feature = "async")] -#[test] -fn same_send_sink() { - let (tx1, _rx) = flume::unbounded::<()>(); - let tx1 = tx1.into_sink(); - let tx2 = tx1.clone(); - - assert!(tx1.same_channel(&tx2)); - - let (tx3, _rx) = flume::unbounded::<()>(); - let tx3 = tx3.into_sink(); - - assert!(!tx1.same_channel(&tx3)); - assert!(!tx2.same_channel(&tx3)); -} - -#[cfg(feature = "async")] -#[test] -fn same_recv_stream() { - let (_tx, rx1) = flume::unbounded::<()>(); - let rx1 = rx1.into_stream(); - let rx2 = rx1.clone(); - - assert!(rx1.same_channel(&rx2)); - - let (_tx, rx3) = flume::unbounded::<()>(); - let rx3 = rx3.into_stream(); - - assert!(!rx1.same_channel(&rx3)); - assert!(!rx2.same_channel(&rx3)); -} diff --git a/vendor/flume/tests/golang.rs b/vendor/flume/tests/golang.rs deleted file mode 100644 index ca00840..0000000 --- a/vendor/flume/tests/golang.rs +++ /dev/null @@ -1,1445 +0,0 @@ -// //! Tests copied from Go and manually rewritten in Rust. -// //! -// //! Source: -// //! - https://github.com/golang/go -// //! -// //! Copyright & License: -// //! - Copyright (c) 2009 The Go Authors -// //! - https://golang.org/AUTHORS -// //! - https://golang.org/LICENSE -// //! - https://golang.org/PATENTS - -// use std::any::Any; -// use std::cell::Cell; -// use std::collections::HashMap; -// use std::sync::{Arc, Condvar, Mutex}; -// use std::thread; -// use std::time::Duration; - -// use flume::{bounded, tick, Receiver, Select, Sender}; - -// fn ms(ms: u64) -> Duration { -// Duration::from_millis(ms) -// } - -// struct Chan<T> { -// inner: Arc<Mutex<ChanInner<T>>>, -// } - -// struct ChanInner<T> { -// s: Option<Sender<T>>, -// r: Receiver<T>, -// } - -// impl<T> Clone for Chan<T> { -// fn clone(&self) -> Chan<T> { -// Chan { -// inner: self.inner.clone(), -// } -// } -// } - -// impl<T> Chan<T> { -// fn send(&self, msg: T) { -// let s = self -// .inner -// .lock() -// .unwrap() -// .s -// .as_ref() -// .expect("sending into closed channel") -// .clone(); -// let _ = s.send(msg); -// } - -// fn try_recv(&self) -> Option<T> { -// let r = self.inner.lock().unwrap().r.clone(); -// r.try_recv().ok() -// } - -// fn recv(&self) -> Option<T> { -// let r = self.inner.lock().unwrap().r.clone(); -// r.recv().ok() -// } - -// fn close(&self) { -// self.inner -// .lock() -// .unwrap() -// .s -// .take() -// .expect("channel already closed"); -// } - -// fn rx(&self) -> Receiver<T> { -// self.inner.lock().unwrap().r.clone() -// } - -// fn tx(&self) -> Sender<T> { -// match self.inner.lock().unwrap().s.as_ref() { -// None => { -// let (s, r) = bounded(0); -// std::mem::forget(r); -// s -// } -// Some(s) => s.clone(), -// } -// } -// } - -// impl<T> Iterator for Chan<T> { -// type Item = T; - -// fn next(&mut self) -> Option<Self::Item> { -// self.recv() -// } -// } - -// impl<'a, T> IntoIterator for &'a Chan<T> { -// type Item = T; -// type IntoIter = Chan<T>; - -// fn into_iter(self) -> Self::IntoIter { -// self.clone() -// } -// } - -// fn make<T>(cap: usize) -> Chan<T> { -// let (s, r) = bounded(cap); -// Chan { -// inner: Arc::new(Mutex::new(ChanInner { s: Some(s), r })), -// } -// } - -// #[derive(Clone)] -// struct WaitGroup(Arc<WaitGroupInner>); - -// struct WaitGroupInner { -// cond: Condvar, -// count: Mutex<i32>, -// } - -// impl WaitGroup { -// fn new() -> WaitGroup { -// WaitGroup(Arc::new(WaitGroupInner { -// cond: Condvar::new(), -// count: Mutex::new(0), -// })) -// } - -// fn add(&self, delta: i32) { -// let mut count = self.0.count.lock().unwrap(); -// *count += delta; -// assert!(*count >= 0); -// self.0.cond.notify_all(); -// } - -// fn done(&self) { -// self.add(-1); -// } - -// fn wait(&self) { -// let mut count = self.0.count.lock().unwrap(); -// while *count > 0 { -// count = self.0.cond.wait(count).unwrap(); -// } -// } -// } - -// struct Defer<F: FnOnce()> { -// f: Option<Box<F>>, -// } - -// impl<F: FnOnce()> Drop for Defer<F> { -// fn drop(&mut self) { -// let f = self.f.take().unwrap(); -// let mut f = Some(f); -// let mut f = move || f.take().unwrap()(); -// f(); -// } -// } - -// macro_rules! defer { -// ($body:expr) => { -// let _defer = Defer { -// f: Some(Box::new(|| $body)), -// }; -// }; -// } - -// macro_rules! go { -// (@parse ref $v:ident, $($tail:tt)*) => {{ -// let ref $v = $v; -// go!(@parse $($tail)*) -// }}; -// (@parse move $v:ident, $($tail:tt)*) => {{ -// let $v = $v; -// go!(@parse $($tail)*) -// }}; -// (@parse $v:ident, $($tail:tt)*) => {{ -// let $v = $v.clone(); -// go!(@parse $($tail)*) -// }}; -// (@parse $body:expr) => { -// ::std::thread::spawn(move || { -// let res = ::std::panic::catch_unwind(::std::panic::AssertUnwindSafe(|| { -// $body -// })); -// if res.is_err() { -// eprintln!("goroutine panicked: {:?}", res); -// ::std::process::abort(); -// } -// }) -// }; -// (@parse $($tail:tt)*) => { -// compile_error!("invalid `go!` syntax") -// }; -// ($($tail:tt)*) => {{ -// go!(@parse $($tail)*) -// }}; -// } - -// // https://github.com/golang/go/blob/master/test/chan/doubleselect.go -// mod doubleselect { -// use super::*; - -// const ITERATIONS: i32 = 10_000; - -// fn sender(n: i32, c1: Chan<i32>, c2: Chan<i32>, c3: Chan<i32>, c4: Chan<i32>) { -// defer! { c1.close() } -// defer! { c2.close() } -// defer! { c3.close() } -// defer! { c4.close() } - -// for i in 0..n { -// select! { -// send(c1.tx(), i) -> _ => {} -// send(c2.tx(), i) -> _ => {} -// send(c3.tx(), i) -> _ => {} -// send(c4.tx(), i) -> _ => {} -// } -// } -// } - -// fn mux(out: Chan<i32>, inp: Chan<i32>, done: Chan<bool>) { -// for v in inp { -// out.send(v); -// } -// done.send(true); -// } - -// fn recver(inp: Chan<i32>) { -// let mut seen = HashMap::new(); - -// for v in &inp { -// if seen.contains_key(&v) { -// panic!("got duplicate value for {}", v); -// } -// seen.insert(v, true); -// } -// } - -// #[test] -// fn main() { -// let c1 = make::<i32>(0); -// let c2 = make::<i32>(0); -// let c3 = make::<i32>(0); -// let c4 = make::<i32>(0); -// let done = make::<bool>(0); -// let cmux = make::<i32>(0); - -// go!(c1, c2, c3, c4, sender(ITERATIONS, c1, c2, c3, c4)); -// go!(cmux, c1, done, mux(cmux, c1, done)); -// go!(cmux, c2, done, mux(cmux, c2, done)); -// go!(cmux, c3, done, mux(cmux, c3, done)); -// go!(cmux, c4, done, mux(cmux, c4, done)); -// go!(done, cmux, { -// done.recv(); -// done.recv(); -// done.recv(); -// done.recv(); -// cmux.close(); -// }); -// recver(cmux); -// } -// } - -// // https://github.com/golang/go/blob/master/test/chan/fifo.go -// mod fifo { -// use super::*; - -// const N: i32 = 10; - -// #[test] -// fn asynch_fifo() { -// let ch = make::<i32>(N as usize); -// for i in 0..N { -// ch.send(i); -// } -// for i in 0..N { -// if ch.recv() != Some(i) { -// panic!("bad receive"); -// } -// } -// } - -// fn chain(ch: Chan<i32>, val: i32, inp: Chan<i32>, out: Chan<i32>) { -// inp.recv(); -// if ch.recv() != Some(val) { -// panic!(val); -// } -// out.send(1); -// } - -// #[test] -// fn synch_fifo() { -// let ch = make::<i32>(0); -// let mut inp = make::<i32>(0); -// let start = inp.clone(); - -// for i in 0..N { -// let out = make::<i32>(0); -// go!(ch, i, inp, out, chain(ch, i, inp, out)); -// inp = out; -// } - -// start.send(0); -// for i in 0..N { -// ch.send(i); -// } -// inp.recv(); -// } -// } - -// // https://github.com/golang/go/blob/master/test/chan/goroutines.go -// mod goroutines { -// use super::*; - -// fn f(left: Chan<i32>, right: Chan<i32>) { -// left.send(right.recv().unwrap()); -// } - -// #[test] -// fn main() { -// let n = 100i32; - -// let leftmost = make::<i32>(0); -// let mut right = leftmost.clone(); -// let mut left = leftmost.clone(); - -// for _ in 0..n { -// right = make::<i32>(0); -// go!(left, right, f(left, right)); -// left = right.clone(); -// } - -// go!(right, right.send(1)); -// leftmost.recv().unwrap(); -// } -// } - -// // https://github.com/golang/go/blob/master/test/chan/nonblock.go -// mod nonblock { -// use super::*; - -// fn i32receiver(c: Chan<i32>, strobe: Chan<bool>) { -// if c.recv().unwrap() != 123 { -// panic!("i32 value"); -// } -// strobe.send(true); -// } - -// fn i32sender(c: Chan<i32>, strobe: Chan<bool>) { -// c.send(234); -// strobe.send(true); -// } - -// fn i64receiver(c: Chan<i64>, strobe: Chan<bool>) { -// if c.recv().unwrap() != 123456 { -// panic!("i64 value"); -// } -// strobe.send(true); -// } - -// fn i64sender(c: Chan<i64>, strobe: Chan<bool>) { -// c.send(234567); -// strobe.send(true); -// } - -// fn breceiver(c: Chan<bool>, strobe: Chan<bool>) { -// if !c.recv().unwrap() { -// panic!("b value"); -// } -// strobe.send(true); -// } - -// fn bsender(c: Chan<bool>, strobe: Chan<bool>) { -// c.send(true); -// strobe.send(true); -// } - -// fn sreceiver(c: Chan<String>, strobe: Chan<bool>) { -// if c.recv().unwrap() != "hello" { -// panic!("x value"); -// } -// strobe.send(true); -// } - -// fn ssender(c: Chan<String>, strobe: Chan<bool>) { -// c.send("hello again".to_string()); -// strobe.send(true); -// } - -// const MAX_TRIES: usize = 10000; // Up to 100ms per test. - -// #[test] -// fn main() { -// let ticker = tick(Duration::new(0, 10_000)); // 10 us -// let sleep = || { -// ticker.recv().unwrap(); -// ticker.recv().unwrap(); -// thread::yield_now(); -// thread::yield_now(); -// thread::yield_now(); -// }; - -// let sync = make::<bool>(0); - -// for buffer in 0..2 { -// let c32 = make::<i32>(buffer); -// let c64 = make::<i64>(buffer); -// let cb = make::<bool>(buffer); -// let cs = make::<String>(buffer); - -// select! { -// recv(c32.rx()) -> _ => panic!("blocked i32sender"), -// default => {} -// } - -// select! { -// recv(c64.rx()) -> _ => panic!("blocked i64sender"), -// default => {} -// } - -// select! { -// recv(cb.rx()) -> _ => panic!("blocked bsender"), -// default => {} -// } - -// select! { -// recv(cs.rx()) -> _ => panic!("blocked ssender"), -// default => {} -// } - -// go!(c32, sync, i32receiver(c32, sync)); -// let mut try = 0; -// loop { -// select! { -// send(c32.tx(), 123) -> _ => break, -// default => { -// try += 1; -// if try > MAX_TRIES { -// println!("i32receiver buffer={}", buffer); -// panic!("fail") -// } -// sleep(); -// } -// } -// } -// sync.recv(); -// go!(c32, sync, i32sender(c32, sync)); -// if buffer > 0 { -// sync.recv(); -// } -// let mut try = 0; -// loop { -// select! { -// recv(c32.rx()) -> v => { -// if v != Ok(234) { -// panic!("i32sender value"); -// } -// break; -// } -// default => { -// try += 1; -// if try > MAX_TRIES { -// println!("i32sender buffer={}", buffer); -// panic!("fail"); -// } -// sleep(); -// } -// } -// } -// if buffer == 0 { -// sync.recv(); -// } - -// go!(c64, sync, i64receiver(c64, sync)); -// let mut try = 0; -// loop { -// select! { -// send(c64.tx(), 123456) -> _ => break, -// default => { -// try += 1; -// if try > MAX_TRIES { -// println!("i64receiver buffer={}", buffer); -// panic!("fail") -// } -// sleep(); -// } -// } -// } -// sync.recv(); -// go!(c64, sync, i64sender(c64, sync)); -// if buffer > 0 { -// sync.recv(); -// } -// let mut try = 0; -// loop { -// select! { -// recv(c64.rx()) -> v => { -// if v != Ok(234567) { -// panic!("i64sender value"); -// } -// break; -// } -// default => { -// try += 1; -// if try > MAX_TRIES { -// println!("i64sender buffer={}", buffer); -// panic!("fail"); -// } -// sleep(); -// } -// } -// } -// if buffer == 0 { -// sync.recv(); -// } - -// go!(cb, sync, breceiver(cb, sync)); -// let mut try = 0; -// loop { -// select! { -// send(cb.tx(), true) -> _ => break, -// default => { -// try += 1; -// if try > MAX_TRIES { -// println!("breceiver buffer={}", buffer); -// panic!("fail") -// } -// sleep(); -// } -// } -// } -// sync.recv(); -// go!(cb, sync, bsender(cb, sync)); -// if buffer > 0 { -// sync.recv(); -// } -// let mut try = 0; -// loop { -// select! { -// recv(cb.rx()) -> v => { -// if v != Ok(true) { -// panic!("bsender value"); -// } -// break; -// } -// default => { -// try += 1; -// if try > MAX_TRIES { -// println!("bsender buffer={}", buffer); -// panic!("fail"); -// } -// sleep(); -// } -// } -// } -// if buffer == 0 { -// sync.recv(); -// } - -// go!(cs, sync, sreceiver(cs, sync)); -// let mut try = 0; -// loop { -// select! { -// send(cs.tx(), "hello".to_string()) -> _ => break, -// default => { -// try += 1; -// if try > MAX_TRIES { -// println!("sreceiver buffer={}", buffer); -// panic!("fail") -// } -// sleep(); -// } -// } -// } -// sync.recv(); -// go!(cs, sync, ssender(cs, sync)); -// if buffer > 0 { -// sync.recv(); -// } -// let mut try = 0; -// loop { -// select! { -// recv(cs.rx()) -> v => { -// if v != Ok("hello again".to_string()) { -// panic!("ssender value"); -// } -// break; -// } -// default => { -// try += 1; -// if try > MAX_TRIES { -// println!("ssender buffer={}", buffer); -// panic!("fail"); -// } -// sleep(); -// } -// } -// } -// if buffer == 0 { -// sync.recv(); -// } -// } -// } -// } - -// // https://github.com/golang/go/blob/master/test/chan/select.go -// mod select { -// use super::*; - -// #[test] -// fn main() { -// let shift = Cell::new(0); -// let counter = Cell::new(0); - -// let get_value = || { -// counter.set(counter.get() + 1); -// 1 << shift.get() -// }; - -// let send = |mut a: Option<&Chan<u32>>, mut b: Option<&Chan<u32>>| { -// let mut i = 0; -// let never = make::<u32>(0); -// loop { -// let nil1 = never.tx(); -// let nil2 = never.tx(); -// let v1 = get_value(); -// let v2 = get_value(); -// select! { -// send(a.map(|c| c.tx()).unwrap_or(nil1), v1) -> _ => { -// i += 1; -// a = None; -// } -// send(b.map(|c| c.tx()).unwrap_or(nil2), v2) -> _ => { -// i += 1; -// b = None; -// } -// default => break, -// } -// shift.set(shift.get() + 1); -// } -// i -// }; - -// let a = make::<u32>(1); -// let b = make::<u32>(1); - -// assert_eq!(send(Some(&a), Some(&b)), 2); - -// let av = a.recv().unwrap(); -// let bv = b.recv().unwrap(); -// assert_eq!(av | bv, 3); - -// assert_eq!(send(Some(&a), None), 1); -// assert_eq!(counter.get(), 10); -// } -// } - -// // https://github.com/golang/go/blob/master/test/chan/select2.go -// mod select2 { -// // TODO -// } - -// // https://github.com/golang/go/blob/master/test/chan/select3.go -// mod select3 { -// // TODO -// } - -// // https://github.com/golang/go/blob/master/test/chan/select4.go -// mod select4 { -// use super::*; - -// #[test] -// fn main() { -// let c = make::<i32>(1); -// let c1 = make::<i32>(0); -// c.send(42); -// select! { -// recv(c1.rx()) -> _ => panic!("BUG"), -// recv(c.rx()) -> v => assert_eq!(v, Ok(42)), -// } -// } -// } - -// // https://github.com/golang/go/blob/master/test/chan/select6.go -// mod select6 { -// use super::*; - -// #[test] -// fn main() { -// let c1 = make::<bool>(0); -// let c2 = make::<bool>(0); -// let c3 = make::<bool>(0); - -// go!(c1, c1.recv()); -// go!(c1, c2, c3, { -// select! { -// recv(c1.rx()) -> _ => panic!("dummy"), -// recv(c2.rx()) -> _ => c3.send(true), -// } -// c1.recv(); -// }); -// go!(c2, c2.send(true)); - -// c3.recv(); -// c1.send(true); -// c1.send(true); -// } -// } - -// // https://github.com/golang/go/blob/master/test/chan/select7.go -// mod select7 { -// use super::*; - -// fn recv1(c: Chan<i32>) { -// c.recv().unwrap(); -// } - -// fn recv2(c: Chan<i32>) { -// select! { -// recv(c.rx()) -> _ => () -// } -// } - -// fn recv3(c: Chan<i32>) { -// let c2 = make::<i32>(1); -// select! { -// recv(c.rx()) -> _ => (), -// recv(c2.rx()) -> _ => () -// } -// } - -// fn send1(recv: fn(Chan<i32>)) { -// let c = make::<i32>(1); -// go!(c, recv(c)); -// thread::yield_now(); -// c.send(1); -// } - -// fn send2(recv: fn(Chan<i32>)) { -// let c = make::<i32>(1); -// go!(c, recv(c)); -// thread::yield_now(); -// select! { -// send(c.tx(), 1) -> _ => () -// } -// } - -// fn send3(recv: fn(Chan<i32>)) { -// let c = make::<i32>(1); -// go!(c, recv(c)); -// thread::yield_now(); -// let c2 = make::<i32>(1); -// select! { -// send(c.tx(), 1) -> _ => (), -// send(c2.tx(), 1) -> _ => () -// } -// } - -// #[test] -// fn main() { -// send1(recv1); -// send2(recv1); -// send3(recv1); -// send1(recv2); -// send2(recv2); -// send3(recv2); -// send1(recv3); -// send2(recv3); -// send3(recv3); -// } -// } - -// // https://github.com/golang/go/blob/master/test/chan/sieve1.go -// mod sieve1 { -// use super::*; - -// fn generate(ch: Chan<i32>) { -// let mut i = 2; -// loop { -// ch.send(i); -// i += 1; -// } -// } - -// fn filter(in_ch: Chan<i32>, out_ch: Chan<i32>, prime: i32) { -// for i in in_ch { -// if i % prime != 0 { -// out_ch.send(i); -// } -// } -// } - -// fn sieve(primes: Chan<i32>) { -// let mut ch = make::<i32>(1); -// go!(ch, generate(ch)); -// loop { -// let prime = ch.recv().unwrap(); -// primes.send(prime); - -// let ch1 = make::<i32>(1); -// go!(ch, ch1, prime, filter(ch, ch1, prime)); -// ch = ch1; -// } -// } - -// #[test] -// fn main() { -// let primes = make::<i32>(1); -// go!(primes, sieve(primes)); - -// let a = [ -// 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, -// 89, 97, -// ]; -// for item in a.iter() { -// let x = primes.recv().unwrap(); -// if x != *item { -// println!("{} != {}", x, item); -// panic!("fail"); -// } -// } -// } -// } - -// // https://github.com/golang/go/blob/master/test/chan/zerosize.go -// mod zerosize { -// use super::*; - -// #[test] -// fn zero_size_struct() { -// struct ZeroSize; -// let _ = make::<ZeroSize>(0); -// } - -// #[test] -// fn zero_size_array() { -// let _ = make::<[u8; 0]>(0); -// } -// } - -// // https://github.com/golang/go/blob/master/src/runtime/chan_test.go -// mod chan_test { -// use super::*; - -// #[test] -// fn test_chan() { -// const N: i32 = 200; - -// for cap in 0..N { -// { -// // Ensure that receive from empty chan blocks. -// let c = make::<i32>(cap as usize); - -// let recv1 = Arc::new(Mutex::new(false)); -// go!(c, recv1, { -// c.recv(); -// *recv1.lock().unwrap() = true; -// }); - -// let recv2 = Arc::new(Mutex::new(false)); -// go!(c, recv2, { -// c.recv(); -// *recv2.lock().unwrap() = true; -// }); - -// thread::sleep(ms(1)); - -// if *recv1.lock().unwrap() || *recv2.lock().unwrap() { -// panic!(); -// } - -// // Ensure that non-blocking receive does not block. -// select! { -// recv(c.rx()) -> _ => panic!(), -// default => {} -// } -// select! { -// recv(c.rx()) -> _ => panic!(), -// default => {} -// } - -// c.send(0); -// c.send(0); -// } - -// { -// // Ensure that send to full chan blocks. -// let c = make::<i32>(cap as usize); -// for i in 0..cap { -// c.send(i); -// } - -// let sent = Arc::new(Mutex::new(0)); -// go!(sent, c, { -// c.send(0); -// *sent.lock().unwrap() = 1; -// }); - -// thread::sleep(ms(1)); - -// if *sent.lock().unwrap() != 0 { -// panic!(); -// } - -// // Ensure that non-blocking send does not block. -// select! { -// send(c.tx(), 0) -> _ => panic!(), -// default => {} -// } -// c.recv(); -// } - -// { -// // Ensure that we receive 0 from closed chan. -// let c = make::<i32>(cap as usize); -// for i in 0..cap { -// c.send(i); -// } -// c.close(); - -// for i in 0..cap { -// let v = c.recv(); -// if v != Some(i) { -// panic!(); -// } -// } - -// if c.recv() != None { -// panic!(); -// } -// if c.try_recv() != None { -// panic!(); -// } -// } - -// { -// // Ensure that close unblocks receive. -// let c = make::<i32>(cap as usize); -// let done = make::<bool>(0); - -// go!(c, done, { -// let v = c.try_recv(); -// done.send(v.is_some()); -// }); - -// thread::sleep(ms(1)); -// c.close(); - -// if !done.recv().unwrap() { -// // panic!(); -// } -// } - -// { -// // Send 100 integers, -// // ensure that we receive them non-corrupted in FIFO order. -// let c = make::<i32>(cap as usize); -// go!(c, { -// for i in 0..100 { -// c.send(i); -// } -// }); -// for i in 0..100 { -// if c.recv() != Some(i) { -// panic!(); -// } -// } - -// // Same, but using recv2. -// go!(c, { -// for i in 0..100 { -// c.send(i); -// } -// }); -// for i in 0..100 { -// if c.recv() != Some(i) { -// panic!(); -// } -// } -// } -// } -// } - -// #[test] -// fn test_nonblock_recv_race() { -// const N: usize = 1000; - -// for _ in 0..N { -// let c = make::<i32>(1); -// c.send(1); - -// let t = go!(c, { -// select! { -// recv(c.rx()) -> _ => {} -// default => panic!("chan is not ready"), -// } -// }); - -// c.close(); -// c.recv(); -// t.join().unwrap(); -// } -// } - -// #[test] -// fn test_nonblock_select_race() { -// const N: usize = 1000; - -// let done = make::<bool>(1); -// for _ in 0..N { -// let c1 = make::<i32>(1); -// let c2 = make::<i32>(1); -// c1.send(1); - -// go!(c1, c2, done, { -// select! { -// recv(c1.rx()) -> _ => {} -// recv(c2.rx()) -> _ => {} -// default => { -// done.send(false); -// return; -// } -// } -// done.send(true); -// }); - -// c2.send(1); -// select! { -// recv(c1.rx()) -> _ => {} -// default => {} -// } -// if !done.recv().unwrap() { -// panic!("no chan is ready"); -// } -// } -// } - -// #[test] -// fn test_nonblock_select_race2() { -// const N: usize = 1000; - -// let done = make::<bool>(1); -// for _ in 0..N { -// let c1 = make::<i32>(1); -// let c2 = make::<i32>(0); -// c1.send(1); - -// go!(c1, c2, done, { -// select! { -// recv(c1.rx()) -> _ => {} -// recv(c2.rx()) -> _ => {} -// default => { -// done.send(false); -// return; -// } -// } -// done.send(true); -// }); - -// c2.close(); -// select! { -// recv(c1.rx()) -> _ => {} -// default => {} -// } -// if !done.recv().unwrap() { -// panic!("no chan is ready"); -// } -// } -// } - -// #[test] -// fn test_self_select() { -// // Ensure that send/recv on the same chan in select -// // does not crash nor deadlock. - -// for &cap in &[0, 10] { -// let wg = WaitGroup::new(); -// wg.add(2); -// let c = make::<i32>(cap); - -// for p in 0..2 { -// let p = p; -// go!(wg, p, c, { -// defer! { wg.done() } -// for i in 0..1000 { -// if p == 0 || i % 2 == 0 { -// select! { -// send(c.tx(), p) -> _ => {} -// recv(c.rx()) -> v => { -// if cap == 0 && v.ok() == Some(p) { -// panic!("self receive"); -// } -// } -// } -// } else { -// select! { -// recv(c.rx()) -> v => { -// if cap == 0 && v.ok() == Some(p) { -// panic!("self receive"); -// } -// } -// send(c.tx(), p) -> _ => {} -// } -// } -// } -// }); -// } -// wg.wait(); -// } -// } - -// #[test] -// fn test_select_stress() { -// let c = vec![ -// make::<i32>(0), -// make::<i32>(0), -// make::<i32>(2), -// make::<i32>(3), -// ]; - -// const N: usize = 10000; - -// // There are 4 goroutines that send N values on each of the chans, -// // + 4 goroutines that receive N values on each of the chans, -// // + 1 goroutine that sends N values on each of the chans in a single select, -// // + 1 goroutine that receives N values on each of the chans in a single select. -// // All these sends, receives and selects interact chaotically at runtime, -// // but we are careful that this whole construct does not deadlock. -// let wg = WaitGroup::new(); -// wg.add(10); - -// for k in 0..4 { -// go!(k, c, wg, { -// for _ in 0..N { -// c[k].send(0); -// } -// wg.done(); -// }); -// go!(k, c, wg, { -// for _ in 0..N { -// c[k].recv(); -// } -// wg.done(); -// }); -// } - -// go!(c, wg, { -// let mut n = [0; 4]; -// let mut c1 = c.iter().map(|c| Some(c.rx().clone())).collect::<Vec<_>>(); - -// for _ in 0..4 * N { -// let index = { -// let mut sel = Select::new(); -// let mut opers = [!0; 4]; -// for &i in &[3, 2, 0, 1] { -// if let Some(c) = &c1[i] { -// opers[i] = sel.recv(c); -// } -// } - -// let oper = sel.select(); -// let mut index = !0; -// for i in 0..4 { -// if opers[i] == oper.index() { -// index = i; -// let _ = oper.recv(c1[i].as_ref().unwrap()); -// break; -// } -// } -// index -// }; - -// n[index] += 1; -// if n[index] == N { -// c1[index] = None; -// } -// } -// wg.done(); -// }); - -// go!(c, wg, { -// let mut n = [0; 4]; -// let mut c1 = c.iter().map(|c| Some(c.tx().clone())).collect::<Vec<_>>(); - -// for _ in 0..4 * N { -// let index = { -// let mut sel = Select::new(); -// let mut opers = [!0; 4]; -// for &i in &[0, 1, 2, 3] { -// if let Some(c) = &c1[i] { -// opers[i] = sel.send(c); -// } -// } - -// let oper = sel.select(); -// let mut index = !0; -// for i in 0..4 { -// if opers[i] == oper.index() { -// index = i; -// let _ = oper.send(c1[i].as_ref().unwrap(), 0); -// break; -// } -// } -// index -// }; - -// n[index] += 1; -// if n[index] == N { -// c1[index] = None; -// } -// } -// wg.done(); -// }); - -// wg.wait(); -// } - -// #[test] -// fn test_select_fairness() { -// const TRIALS: usize = 10000; - -// let c1 = make::<u8>(TRIALS + 1); -// let c2 = make::<u8>(TRIALS + 1); - -// for _ in 0..TRIALS + 1 { -// c1.send(1); -// c2.send(2); -// } - -// let c3 = make::<u8>(0); -// let c4 = make::<u8>(0); -// let out = make::<u8>(0); -// let done = make::<u8>(0); -// let wg = WaitGroup::new(); - -// wg.add(1); -// go!(wg, c1, c2, c3, c4, out, done, { -// defer! { wg.done() }; -// loop { -// let b; -// select! { -// recv(c3.rx()) -> m => b = m.unwrap(), -// recv(c4.rx()) -> m => b = m.unwrap(), -// recv(c1.rx()) -> m => b = m.unwrap(), -// recv(c2.rx()) -> m => b = m.unwrap(), -// } -// select! { -// send(out.tx(), b) -> _ => {} -// recv(done.rx()) -> _ => return, -// } -// } -// }); - -// let (mut cnt1, mut cnt2) = (0, 0); -// for _ in 0..TRIALS { -// match out.recv() { -// Some(1) => cnt1 += 1, -// Some(2) => cnt2 += 1, -// b => panic!("unexpected value {:?} on channel", b), -// } -// } - -// // If the select in the goroutine is fair, -// // cnt1 and cnt2 should be about the same value. -// // With 10,000 trials, the expected margin of error at -// // a confidence level of five nines is 4.4172 / (2 * Sqrt(10000)). - -// let r = cnt1 as f64 / TRIALS as f64; -// let e = (r - 0.5).abs(); - -// if e > 4.4172 / (2.0 * (TRIALS as f64).sqrt()) { -// panic!( -// "unfair select: in {} trials, results were {}, {}", -// TRIALS, cnt1, cnt2, -// ); -// } - -// done.close(); -// wg.wait(); -// } - -// #[test] -// fn test_chan_send_interface() { -// struct Mt; - -// let c = make::<Box<dyn Any>>(1); -// c.send(Box::new(Mt)); - -// select! { -// send(c.tx(), Box::new(Mt)) -> _ => {} -// default => {} -// } - -// select! { -// send(c.tx(), Box::new(Mt)) -> _ => {} -// send(c.tx(), Box::new(Mt)) -> _ => {} -// default => {} -// } -// } - -// #[test] -// fn test_pseudo_random_send() { -// const N: usize = 100; - -// for cap in 0..N { -// let c = make::<i32>(cap); -// let l = Arc::new(Mutex::new(vec![0i32; N])); -// let done = make::<bool>(0); - -// go!(c, done, l, { -// let mut l = l.lock().unwrap(); -// for i in 0..N { -// thread::yield_now(); -// l[i] = c.recv().unwrap(); -// } -// done.send(true); -// }); - -// for _ in 0..N { -// select! { -// send(c.tx(), 1) -> _ => {} -// send(c.tx(), 0) -> _ => {} -// } -// } -// done.recv(); - -// let mut n0 = 0; -// let mut n1 = 0; -// for &i in l.lock().unwrap().iter() { -// n0 += (i + 1) % 2; -// n1 += i; -// } - -// if n0 <= N as i32 / 10 || n1 <= N as i32 / 10 { -// panic!( -// "Want pseudorandom, got {} zeros and {} ones (chan cap {})", -// n0, n1, cap, -// ); -// } -// } -// } - -// #[test] -// fn test_multi_consumer() { -// const NWORK: usize = 23; -// const NITER: usize = 271828; - -// let pn = [2, 3, 7, 11, 13, 17, 19, 23, 27, 31]; - -// let q = make::<i32>(NWORK * 3); -// let r = make::<i32>(NWORK * 3); - -// let wg = WaitGroup::new(); -// for i in 0..NWORK { -// wg.add(1); -// let w = i; -// go!(q, r, wg, pn, { -// for v in &q { -// if pn[w % pn.len()] == v { -// thread::yield_now(); -// } -// r.send(v); -// } -// wg.done(); -// }); -// } - -// let expect = Arc::new(Mutex::new(0)); -// go!(q, r, expect, wg, pn, { -// for i in 0..NITER { -// let v = pn[i % pn.len()]; -// *expect.lock().unwrap() += v; -// q.send(v); -// } -// q.close(); -// wg.wait(); -// r.close(); -// }); - -// let mut n = 0; -// let mut s = 0; -// for v in &r { -// n += 1; -// s += v; -// } - -// if n != NITER || s != *expect.lock().unwrap() { -// panic!(); -// } -// } - -// #[test] -// fn test_select_duplicate_channel() { -// // This test makes sure we can queue a G on -// // the same channel multiple times. -// let c = make::<i32>(0); -// let d = make::<i32>(0); -// let e = make::<i32>(0); - -// go!(c, d, e, { -// select! { -// recv(c.rx()) -> _ => {} -// recv(d.rx()) -> _ => {} -// recv(e.rx()) -> _ => {} -// } -// e.send(9); -// }); -// thread::sleep(ms(1)); - -// go!(c, c.recv()); -// thread::sleep(ms(1)); - -// d.send(7); -// e.recv(); -// c.send(8); -// } -// } - -// // https://github.com/golang/go/blob/master/test/closedchan.go -// mod closedchan { -// // TODO -// } - -// // https://github.com/golang/go/blob/master/src/runtime/chanbarrier_test.go -// mod chanbarrier_test { -// // TODO -// } - -// // https://github.com/golang/go/blob/master/src/runtime/race/testdata/chan_test.go -// mod race_chan_test { -// // TODO -// } - -// // https://github.com/golang/go/blob/master/test/ken/chan.go -// mod chan { -// // TODO -// } - -// // https://github.com/golang/go/blob/master/test/ken/chan1.go -// mod chan1 { -// // TODO -// } diff --git a/vendor/flume/tests/iter.rs b/vendor/flume/tests/iter.rs deleted file mode 100644 index 4d69adb..0000000 --- a/vendor/flume/tests/iter.rs +++ /dev/null @@ -1,112 +0,0 @@ -//! Tests for iteration over receivers. - -extern crate crossbeam_utils; - -use flume::unbounded; -use crossbeam_utils::thread::scope; - -#[test] -fn nested_recv_iter() { - let (s, r) = unbounded::<i32>(); - let (total_s, total_r) = unbounded::<i32>(); - - scope(|scope| { - scope.spawn(move |_| { - let mut acc = 0; - for x in r.iter() { - acc += x; - } - total_s.send(acc).unwrap(); - }); - - s.send(3).unwrap(); - s.send(1).unwrap(); - s.send(2).unwrap(); - drop(s); - assert_eq!(total_r.recv().unwrap(), 6); - }) - .unwrap(); -} - -#[test] -fn recv_iter_break() { - let (s, r) = unbounded::<i32>(); - let (count_s, count_r) = unbounded(); - - scope(|scope| { - scope.spawn(move |_| { - let mut count = 0; - for x in r.iter() { - if count >= 3 { - break; - } else { - count += x; - } - } - count_s.send(count).unwrap(); - }); - - s.send(2).unwrap(); - s.send(2).unwrap(); - s.send(2).unwrap(); - let _ = s.send(2); - drop(s); - assert_eq!(count_r.recv().unwrap(), 4); - }) - .unwrap(); -} - -#[test] -fn recv_try_iter() { - let (request_s, request_r) = unbounded(); - let (response_s, response_r) = unbounded(); - - scope(|scope| { - scope.spawn(move |_| { - let mut count = 0; - loop { - for x in response_r.try_iter() { - count += x; - if count == 6 { - return; - } - } - request_s.send(()).unwrap(); - } - }); - - for _ in request_r.iter() { - if response_s.send(2).is_err() { - break; - } - } - }) - .unwrap(); -} - -#[test] -fn recv_into_iter_owned() { - let mut iter = { - let (s, r) = unbounded::<i32>(); - s.send(1).unwrap(); - s.send(2).unwrap(); - r.into_iter() - }; - - assert_eq!(iter.next().unwrap(), 1); - assert_eq!(iter.next().unwrap(), 2); - assert_eq!(iter.next().is_none(), true); -} - -#[test] -fn recv_into_iter_borrowed() { - let (s, r) = unbounded::<i32>(); - s.send(1).unwrap(); - s.send(2).unwrap(); - drop(s); - - let mut iter = (&r).into_iter(); - assert_eq!(iter.next().unwrap(), 1); - assert_eq!(iter.next().unwrap(), 2); - assert_eq!(iter.next().is_none(), true); -} diff --git a/vendor/flume/tests/list.rs b/vendor/flume/tests/list.rs deleted file mode 100644 index 851af88..0000000 --- a/vendor/flume/tests/list.rs +++ /dev/null @@ -1,536 +0,0 @@ -//! Tests for the list channel flavor. - -extern crate crossbeam_utils; -extern crate rand; - -use std::any::Any; -use std::sync::atomic::AtomicUsize; -use std::sync::atomic::Ordering; -use std::thread; -use std::time::Duration; - -use flume::{unbounded, Receiver}; -use flume::{RecvError, RecvTimeoutError, TryRecvError}; -use flume::{SendError, SendTimeoutError, TrySendError}; -use crossbeam_utils::thread::scope; -use rand::{thread_rng, Rng}; - -fn ms(ms: u64) -> Duration { - Duration::from_millis(ms) -} - -#[test] -fn smoke() { - let (s, r) = unbounded(); - s.try_send(7).unwrap(); - assert_eq!(r.try_recv(), Ok(7)); - - s.send(8).unwrap(); - assert_eq!(r.recv(), Ok(8)); - - assert_eq!(r.try_recv(), Err(TryRecvError::Empty)); - assert_eq!(r.recv_timeout(ms(1000)), Err(RecvTimeoutError::Timeout)); -} - -#[test] -fn capacity() { - let (s, r) = unbounded::<()>(); - assert_eq!(s.capacity(), None); - assert_eq!(r.capacity(), None); -} - -#[test] -fn len_empty_full() { - let (s, r) = unbounded(); - - assert_eq!(s.len(), 0); - assert_eq!(s.is_empty(), true); - assert_eq!(s.is_full(), false); - assert_eq!(r.len(), 0); - assert_eq!(r.is_empty(), true); - assert_eq!(r.is_full(), false); - - s.send(()).unwrap(); - - assert_eq!(s.len(), 1); - assert_eq!(s.is_empty(), false); - assert_eq!(s.is_full(), false); - assert_eq!(r.len(), 1); - assert_eq!(r.is_empty(), false); - assert_eq!(r.is_full(), false); - - r.recv().unwrap(); - - assert_eq!(s.len(), 0); - assert_eq!(s.is_empty(), true); - assert_eq!(s.is_full(), false); - assert_eq!(r.len(), 0); - assert_eq!(r.is_empty(), true); - assert_eq!(r.is_full(), false); -} - -#[test] -fn try_recv() { - let (s, r) = unbounded(); - - scope(|scope| { - scope.spawn(move |_| { - assert_eq!(r.try_recv(), Err(TryRecvError::Empty)); - thread::sleep(ms(1500)); - assert_eq!(r.try_recv(), Ok(7)); - thread::sleep(ms(500)); - assert_eq!(r.try_recv(), Err(TryRecvError::Disconnected)); - }); - scope.spawn(move |_| { - thread::sleep(ms(1000)); - s.send(7).unwrap(); - }); - }) - .unwrap(); -} - -#[test] -fn recv() { - let (s, r) = unbounded(); - - scope(|scope| { - scope.spawn(move |_| { - assert_eq!(r.recv(), Ok(7)); - thread::sleep(ms(1000)); - assert_eq!(r.recv(), Ok(8)); - thread::sleep(ms(1000)); - assert_eq!(r.recv(), Ok(9)); - assert!(r.recv().is_err()); - }); - scope.spawn(move |_| { - thread::sleep(ms(1500)); - s.send(7).unwrap(); - s.send(8).unwrap(); - s.send(9).unwrap(); - }); - }) - .unwrap(); -} - -#[test] -fn recv_timeout() { - let (s, r) = unbounded::<i32>(); - - scope(|scope| { - scope.spawn(move |_| { - assert_eq!(r.recv_timeout(ms(1000)), Err(RecvTimeoutError::Timeout)); - assert_eq!(r.recv_timeout(ms(1000)), Ok(7)); - assert_eq!( - r.recv_timeout(ms(1000)), - Err(RecvTimeoutError::Disconnected) - ); - }); - scope.spawn(move |_| { - thread::sleep(ms(1500)); - s.send(7).unwrap(); - }); - }) - .unwrap(); -} - -#[test] -fn try_send() { - let (s, r) = unbounded(); - for i in 0..1000 { - assert_eq!(s.try_send(i), Ok(())); - } - - drop(r); - assert_eq!(s.try_send(777), Err(TrySendError::Disconnected(777))); -} - -#[test] -fn send() { - let (s, r) = unbounded(); - for i in 0..1000 { - assert_eq!(s.send(i), Ok(())); - } - - drop(r); - assert_eq!(s.send(777), Err(SendError(777))); -} - -#[test] -fn send_timeout() { - let (s, r) = unbounded(); - for i in 0..1000 { - assert_eq!(s.send_timeout(i, ms(i as u64)), Ok(())); - } - - drop(r); - assert_eq!( - s.send_timeout(777, ms(0)), - Err(SendTimeoutError::Disconnected(777)) - ); -} - -#[test] -fn send_after_disconnect() { - let (s, r) = unbounded(); - - s.send(1).unwrap(); - s.send(2).unwrap(); - s.send(3).unwrap(); - - drop(r); - - assert_eq!(s.send(4), Err(SendError(4))); - assert_eq!(s.try_send(5), Err(TrySendError::Disconnected(5))); - assert_eq!( - s.send_timeout(6, ms(0)), - Err(SendTimeoutError::Disconnected(6)) - ); -} - -#[test] -fn recv_after_disconnect() { - let (s, r) = unbounded(); - - s.send(1).unwrap(); - s.send(2).unwrap(); - s.send(3).unwrap(); - - drop(s); - - assert_eq!(r.recv(), Ok(1)); - assert_eq!(r.recv(), Ok(2)); - assert_eq!(r.recv(), Ok(3)); - assert!(r.recv().is_err()); -} - -#[test] -fn len() { - let (s, r) = unbounded(); - - assert_eq!(s.len(), 0); - assert_eq!(r.len(), 0); - - for i in 0..50 { - s.send(i).unwrap(); - assert_eq!(s.len(), i + 1); - } - - for i in 0..50 { - r.recv().unwrap(); - assert_eq!(r.len(), 50 - i - 1); - } - - assert_eq!(s.len(), 0); - assert_eq!(r.len(), 0); -} - -#[test] -fn disconnect_wakes_receiver() { - let (s, r) = unbounded::<()>(); - - scope(|scope| { - scope.spawn(move |_| { - assert!(r.recv().is_err()); - }); - scope.spawn(move |_| { - thread::sleep(ms(1000)); - drop(s); - }); - }) - .unwrap(); -} - -#[test] -fn spsc() { - const COUNT: usize = 100_000; - - let (s, r) = unbounded(); - - scope(|scope| { - scope.spawn(move |_| { - for i in 0..COUNT { - assert_eq!(r.recv(), Ok(i)); - } - assert!(r.recv().is_err()); - }); - scope.spawn(move |_| { - for i in 0..COUNT { - s.send(i).unwrap(); - } - }); - }) - .unwrap(); -} - -#[test] -fn mpmc() { - const COUNT: usize = 25_000; - const THREADS: usize = 4; - - let (s, r) = unbounded::<usize>(); - let v = (0..COUNT).map(|_| AtomicUsize::new(0)).collect::<Vec<_>>(); - - scope(|scope| { - for _ in 0..THREADS { - scope.spawn(|_| { - for _ in 0..COUNT { - let n = r.recv().unwrap(); - v[n].fetch_add(1, Ordering::SeqCst); - } - }); - } - for _ in 0..THREADS { - scope.spawn(|_| { - for i in 0..COUNT { - s.send(i).unwrap(); - } - }); - } - }) - .unwrap(); - - assert_eq!(r.try_recv(), Err(TryRecvError::Empty)); - - for c in v { - assert_eq!(c.load(Ordering::SeqCst), THREADS); - } -} - -#[test] -fn stress_oneshot() { - const COUNT: usize = 10_000; - - for _ in 0..COUNT { - let (s, r) = unbounded(); - - scope(|scope| { - scope.spawn(|_| r.recv().unwrap()); - scope.spawn(|_| s.send(0).unwrap()); - }) - .unwrap(); - } -} - -#[test] -fn stress_iter() { - const COUNT: usize = 100_000; - - let (request_s, request_r) = unbounded(); - let (response_s, response_r) = unbounded(); - - scope(|scope| { - scope.spawn(move |_| { - let mut count = 0; - loop { - for x in response_r.try_iter() { - count += x; - if count == COUNT { - return; - } - } - request_s.send(()).unwrap(); - } - }); - - for _ in request_r.iter() { - if response_s.send(1).is_err() { - break; - } - } - }) - .unwrap(); -} - -#[test] -fn stress_timeout_two_threads() { - const COUNT: usize = 100; - - let (s, r) = unbounded(); - - scope(|scope| { - scope.spawn(|_| { - for i in 0..COUNT { - if i % 2 == 0 { - thread::sleep(ms(50)); - } - s.send(i).unwrap(); - } - }); - - scope.spawn(|_| { - for i in 0..COUNT { - if i % 2 == 0 { - thread::sleep(ms(50)); - } - loop { - if let Ok(x) = r.recv_timeout(ms(10)) { - assert_eq!(x, i); - break; - } - } - } - }); - }) - .unwrap(); -} - -#[test] -fn drops() { - static DROPS: AtomicUsize = AtomicUsize::new(0); - - #[derive(Debug, PartialEq)] - struct DropCounter; - - impl Drop for DropCounter { - fn drop(&mut self) { - DROPS.fetch_add(1, Ordering::SeqCst); - } - } - - let mut rng = thread_rng(); - - for _ in 0..100 { - let steps = rng.gen_range(0..10_000); - let additional = rng.gen_range(0..1000); - - DROPS.store(0, Ordering::SeqCst); - let (s, r) = unbounded::<DropCounter>(); - - scope(|scope| { - scope.spawn(|_| { - for _ in 0..steps { - r.recv().unwrap(); - } - }); - - scope.spawn(|_| { - for _ in 0..steps { - s.send(DropCounter).unwrap(); - } - }); - }) - .unwrap(); - - for _ in 0..additional { - s.try_send(DropCounter).unwrap(); - } - - assert_eq!(DROPS.load(Ordering::SeqCst), steps); - drop(s); - drop(r); - assert_eq!(DROPS.load(Ordering::SeqCst), steps + additional); - } -} - -#[test] -fn linearizable() { - const COUNT: usize = 25_000; - const THREADS: usize = 4; - - let (s, r) = unbounded(); - - scope(|scope| { - for _ in 0..THREADS { - scope.spawn(|_| { - for _ in 0..COUNT { - s.send(0).unwrap(); - r.try_recv().unwrap(); - } - }); - } - }) - .unwrap(); -} - -// #[test] -// fn fairness() { -// const COUNT: usize = 10_000; - -// let (s1, r1) = unbounded::<()>(); -// let (s2, r2) = unbounded::<()>(); - -// for _ in 0..COUNT { -// s1.send(()).unwrap(); -// s2.send(()).unwrap(); -// } - -// let mut hits = [0usize; 2]; -// for _ in 0..COUNT { -// select! { -// recv(r1) -> _ => hits[0] += 1, -// recv(r2) -> _ => hits[1] += 1, -// } -// } -// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2)); -// } - -// #[test] -// fn fairness_duplicates() { -// const COUNT: usize = 10_000; - -// let (s, r) = unbounded(); - -// for _ in 0..COUNT { -// s.send(()).unwrap(); -// } - -// let mut hits = [0usize; 5]; -// for _ in 0..COUNT { -// select! { -// recv(r) -> _ => hits[0] += 1, -// recv(r) -> _ => hits[1] += 1, -// recv(r) -> _ => hits[2] += 1, -// recv(r) -> _ => hits[3] += 1, -// recv(r) -> _ => hits[4] += 1, -// } -// } -// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2)); -// } - -// #[test] -// fn recv_in_send() { -// let (s, r) = unbounded(); -// s.send(()).unwrap(); - -// select! { -// send(s, assert_eq!(r.recv(), Ok(()))) -> _ => {} -// } -// } - -#[test] -fn channel_through_channel() { - const COUNT: usize = 1000; - - type T = Box<dyn Any + Send>; - - let (s, r) = unbounded::<T>(); - - scope(|scope| { - scope.spawn(move |_| { - let mut s = s; - - for _ in 0..COUNT { - let (new_s, new_r) = unbounded(); - let new_r: T = Box::new(Some(new_r)); - - s.send(new_r).unwrap(); - s = new_s; - } - }); - - scope.spawn(move |_| { - let mut r = r; - - for _ in 0..COUNT { - r = r - .recv() - .unwrap() - .downcast_mut::<Option<Receiver<T>>>() - .unwrap() - .take() - .unwrap() - } - }); - }) - .unwrap(); -} diff --git a/vendor/flume/tests/method_sharing.rs b/vendor/flume/tests/method_sharing.rs deleted file mode 100644 index 24173ea..0000000 --- a/vendor/flume/tests/method_sharing.rs +++ /dev/null @@ -1,39 +0,0 @@ -#[cfg(feature = "async")] -use flume::*; - -#[cfg(feature = "async")] -#[async_std::test] -async fn sender() { - let (sender, receiver) = bounded(1); - - let sender_fut = sender.send_async(()); - assert_eq!(sender.is_disconnected(), sender_fut.is_disconnected()); - assert_eq!(sender.is_empty(), sender_fut.is_empty()); - assert_eq!(sender.is_full(), sender_fut.is_full()); - assert_eq!(sender.len(), sender_fut.len()); - assert_eq!(sender.capacity(), sender_fut.capacity()); - - let sender_sink = sender.sink(); - assert_eq!(sender.is_disconnected(), sender_sink.is_disconnected()); - assert_eq!(sender.is_empty(), sender_sink.is_empty()); - assert_eq!(sender.is_full(), sender_sink.is_full()); - assert_eq!(sender.len(), sender_sink.len()); - assert_eq!(sender.capacity(), sender_sink.capacity()); - - let receiver_fut = receiver.recv_async(); - assert_eq!(receiver.is_disconnected(), receiver_fut.is_disconnected()); - assert_eq!(receiver.is_empty(), receiver_fut.is_empty()); - assert_eq!(receiver.is_full(), receiver_fut.is_full()); - assert_eq!(receiver.len(), receiver_fut.len()); - assert_eq!(receiver.capacity(), receiver_fut.capacity()); - - let receiver_stream = receiver.stream(); - assert_eq!( - receiver.is_disconnected(), - receiver_stream.is_disconnected() - ); - assert_eq!(receiver.is_empty(), receiver_stream.is_empty()); - assert_eq!(receiver.is_full(), receiver_stream.is_full()); - assert_eq!(receiver.len(), receiver_stream.len()); - assert_eq!(receiver.capacity(), receiver_stream.capacity()); -} diff --git a/vendor/flume/tests/mpsc.rs b/vendor/flume/tests/mpsc.rs deleted file mode 100644 index 213b9d8..0000000 --- a/vendor/flume/tests/mpsc.rs +++ /dev/null @@ -1,2095 +0,0 @@ -//! Tests copied from `std::sync::mpsc`. -//! -//! This is a copy of tests for the `std::sync::mpsc` channels from the standard library, but -//! modified to work with `crossbeam-channel` instead. -//! -//! Minor tweaks were needed to make the tests compile: -//! -//! - Replace `box` syntax with `Box::new`. -//! - Replace all uses of `Select` with `select!`. -//! - Change the imports. -//! - Join all spawned threads. -//! - Removed assertion from oneshot_multi_thread_send_close_stress tests. -//! -//! Source: -//! - https://github.com/rust-lang/rust/tree/master/src/libstd/sync/mpsc -//! -//! Copyright & License: -//! - Copyright 2013-2014 The Rust Project Developers -//! - Apache License, Version 2.0 or MIT license, at your option -//! - https://github.com/rust-lang/rust/blob/master/COPYRIGHT -//! - https://www.rust-lang.org/en-US/legal.html - -#[macro_use] -extern crate crossbeam_channel as cc; - -use std::sync::mpsc::{RecvError, RecvTimeoutError, TryRecvError}; -use std::sync::mpsc::{SendError, TrySendError}; -use std::thread::JoinHandle; -use std::time::Duration; - -pub struct Sender<T> { - pub inner: cc::Sender<T>, -} - -impl<T> Sender<T> { - pub fn send(&self, t: T) -> Result<(), SendError<T>> { - self.inner.send(t).map_err(|cc::SendError(m)| SendError(m)) - } -} - -impl<T> Clone for Sender<T> { - fn clone(&self) -> Sender<T> { - Sender { - inner: self.inner.clone(), - } - } -} - -pub struct SyncSender<T> { - pub inner: cc::Sender<T>, -} - -impl<T> SyncSender<T> { - pub fn send(&self, t: T) -> Result<(), SendError<T>> { - self.inner.send(t).map_err(|cc::SendError(m)| SendError(m)) - } - - pub fn try_send(&self, t: T) -> Result<(), TrySendError<T>> { - self.inner.try_send(t).map_err(|err| match err { - cc::TrySendError::Full(m) => TrySendError::Full(m), - cc::TrySendError::Disconnected(m) => TrySendError::Disconnected(m), - }) - } -} - -impl<T> Clone for SyncSender<T> { - fn clone(&self) -> SyncSender<T> { - SyncSender { - inner: self.inner.clone(), - } - } -} - -pub struct Receiver<T> { - pub inner: cc::Receiver<T>, -} - -impl<T> Receiver<T> { - pub fn try_recv(&self) -> Result<T, TryRecvError> { - self.inner.try_recv().map_err(|err| match err { - cc::TryRecvError::Empty => TryRecvError::Empty, - cc::TryRecvError::Disconnected => TryRecvError::Disconnected, - }) - } - - pub fn recv(&self) -> Result<T, RecvError> { - self.inner.recv().map_err(|_| RecvError) - } - - pub fn recv_timeout(&self, timeout: Duration) -> Result<T, RecvTimeoutError> { - self.inner.recv_timeout(timeout).map_err(|err| match err { - cc::RecvTimeoutError::Timeout => RecvTimeoutError::Timeout, - cc::RecvTimeoutError::Disconnected => RecvTimeoutError::Disconnected, - }) - } - - pub fn iter(&self) -> Iter<T> { - Iter { inner: self } - } - - pub fn try_iter(&self) -> TryIter<T> { - TryIter { inner: self } - } -} - -impl<'a, T> IntoIterator for &'a Receiver<T> { - type Item = T; - type IntoIter = Iter<'a, T>; - - fn into_iter(self) -> Iter<'a, T> { - self.iter() - } -} - -impl<T> IntoIterator for Receiver<T> { - type Item = T; - type IntoIter = IntoIter<T>; - - fn into_iter(self) -> IntoIter<T> { - IntoIter { inner: self } - } -} - -pub struct TryIter<'a, T: 'a> { - inner: &'a Receiver<T>, -} - -impl<'a, T> Iterator for TryIter<'a, T> { - type Item = T; - - fn next(&mut self) -> Option<T> { - self.inner.try_recv().ok() - } -} - -pub struct Iter<'a, T: 'a> { - inner: &'a Receiver<T>, -} - -impl<'a, T> Iterator for Iter<'a, T> { - type Item = T; - - fn next(&mut self) -> Option<T> { - self.inner.recv().ok() - } -} - -pub struct IntoIter<T> { - inner: Receiver<T>, -} - -impl<T> Iterator for IntoIter<T> { - type Item = T; - - fn next(&mut self) -> Option<T> { - self.inner.recv().ok() - } -} - -pub fn channel<T>() -> (Sender<T>, Receiver<T>) { - let (s, r) = cc::unbounded(); - let s = Sender { inner: s }; - let r = Receiver { inner: r }; - (s, r) -} - -pub fn sync_channel<T>(bound: usize) -> (SyncSender<T>, Receiver<T>) { - let (s, r) = cc::bounded(bound); - let s = SyncSender { inner: s }; - let r = Receiver { inner: r }; - (s, r) -} - -macro_rules! select { - ( - $($name:pat = $rx:ident.$meth:ident() => $code:expr),+ - ) => ({ - crossbeam_channel_internal! { - $( - recv(($rx).inner) -> res => { - let $name = res.map_err(|_| ::std::sync::mpsc::RecvError); - $code - } - )+ - } - }) -} - -// Source: https://github.com/rust-lang/rust/blob/master/src/libstd/sync/mpsc/mod.rs -mod channel_tests { - use super::*; - - use std::env; - use std::thread; - use std::time::{Duration, Instant}; - - pub fn stress_factor() -> usize { - match env::var("RUST_TEST_STRESS") { - Ok(val) => val.parse().unwrap(), - Err(..) => 1, - } - } - - #[test] - fn smoke() { - let (tx, rx) = channel::<i32>(); - tx.send(1).unwrap(); - assert_eq!(rx.recv().unwrap(), 1); - } - - #[test] - fn drop_full() { - let (tx, _rx) = channel::<Box<isize>>(); - tx.send(Box::new(1)).unwrap(); - } - - #[test] - fn drop_full_shared() { - let (tx, _rx) = channel::<Box<isize>>(); - drop(tx.clone()); - drop(tx.clone()); - tx.send(Box::new(1)).unwrap(); - } - - #[test] - fn smoke_shared() { - let (tx, rx) = channel::<i32>(); - tx.send(1).unwrap(); - assert_eq!(rx.recv().unwrap(), 1); - let tx = tx.clone(); - tx.send(1).unwrap(); - assert_eq!(rx.recv().unwrap(), 1); - } - - #[test] - fn smoke_threads() { - let (tx, rx) = channel::<i32>(); - let t = thread::spawn(move || { - tx.send(1).unwrap(); - }); - assert_eq!(rx.recv().unwrap(), 1); - t.join().unwrap(); - } - - #[test] - fn smoke_port_gone() { - let (tx, rx) = channel::<i32>(); - drop(rx); - assert!(tx.send(1).is_err()); - } - - #[test] - fn smoke_shared_port_gone() { - let (tx, rx) = channel::<i32>(); - drop(rx); - assert!(tx.send(1).is_err()) - } - - #[test] - fn smoke_shared_port_gone2() { - let (tx, rx) = channel::<i32>(); - drop(rx); - let tx2 = tx.clone(); - drop(tx); - assert!(tx2.send(1).is_err()); - } - - #[test] - fn port_gone_concurrent() { - let (tx, rx) = channel::<i32>(); - let t = thread::spawn(move || { - rx.recv().unwrap(); - }); - while tx.send(1).is_ok() {} - t.join().unwrap(); - } - - #[test] - fn port_gone_concurrent_shared() { - let (tx, rx) = channel::<i32>(); - let tx2 = tx.clone(); - let t = thread::spawn(move || { - rx.recv().unwrap(); - }); - while tx.send(1).is_ok() && tx2.send(1).is_ok() {} - t.join().unwrap(); - } - - #[test] - fn smoke_chan_gone() { - let (tx, rx) = channel::<i32>(); - drop(tx); - assert!(rx.recv().is_err()); - } - - #[test] - fn smoke_chan_gone_shared() { - let (tx, rx) = channel::<()>(); - let tx2 = tx.clone(); - drop(tx); - drop(tx2); - assert!(rx.recv().is_err()); - } - - #[test] - fn chan_gone_concurrent() { - let (tx, rx) = channel::<i32>(); - let t = thread::spawn(move || { - tx.send(1).unwrap(); - tx.send(1).unwrap(); - }); - while rx.recv().is_ok() {} - t.join().unwrap(); - } - - #[test] - fn stress() { - let (tx, rx) = channel::<i32>(); - let t = thread::spawn(move || { - for _ in 0..10000 { - tx.send(1).unwrap(); - } - }); - for _ in 0..10000 { - assert_eq!(rx.recv().unwrap(), 1); - } - t.join().ok().unwrap(); - } - - #[test] - fn stress_shared() { - const AMT: u32 = 10000; - const NTHREADS: u32 = 8; - let (tx, rx) = channel::<i32>(); - - let t = thread::spawn(move || { - for _ in 0..AMT * NTHREADS { - assert_eq!(rx.recv().unwrap(), 1); - } - match rx.try_recv() { - Ok(..) => panic!(), - _ => {} - } - }); - - let mut ts = Vec::with_capacity(NTHREADS as usize); - for _ in 0..NTHREADS { - let tx = tx.clone(); - let t = thread::spawn(move || { - for _ in 0..AMT { - tx.send(1).unwrap(); - } - }); - ts.push(t); - } - drop(tx); - t.join().ok().unwrap(); - for t in ts { - t.join().unwrap(); - } - } - - #[test] - fn send_from_outside_runtime() { - let (tx1, rx1) = channel::<()>(); - let (tx2, rx2) = channel::<i32>(); - let t1 = thread::spawn(move || { - tx1.send(()).unwrap(); - for _ in 0..40 { - assert_eq!(rx2.recv().unwrap(), 1); - } - }); - rx1.recv().unwrap(); - let t2 = thread::spawn(move || { - for _ in 0..40 { - tx2.send(1).unwrap(); - } - }); - t1.join().ok().unwrap(); - t2.join().ok().unwrap(); - } - - #[test] - fn recv_from_outside_runtime() { - let (tx, rx) = channel::<i32>(); - let t = thread::spawn(move || { - for _ in 0..40 { - assert_eq!(rx.recv().unwrap(), 1); - } - }); - for _ in 0..40 { - tx.send(1).unwrap(); - } - t.join().ok().unwrap(); - } - - #[test] - fn no_runtime() { - let (tx1, rx1) = channel::<i32>(); - let (tx2, rx2) = channel::<i32>(); - let t1 = thread::spawn(move || { - assert_eq!(rx1.recv().unwrap(), 1); - tx2.send(2).unwrap(); - }); - let t2 = thread::spawn(move || { - tx1.send(1).unwrap(); - assert_eq!(rx2.recv().unwrap(), 2); - }); - t1.join().ok().unwrap(); - t2.join().ok().unwrap(); - } - - #[test] - fn oneshot_single_thread_close_port_first() { - // Simple test of closing without sending - let (_tx, rx) = channel::<i32>(); - drop(rx); - } - - #[test] - fn oneshot_single_thread_close_chan_first() { - // Simple test of closing without sending - let (tx, _rx) = channel::<i32>(); - drop(tx); - } - - #[test] - fn oneshot_single_thread_send_port_close() { - // Testing that the sender cleans up the payload if receiver is closed - let (tx, rx) = channel::<Box<i32>>(); - drop(rx); - assert!(tx.send(Box::new(0)).is_err()); - } - - #[test] - fn oneshot_single_thread_recv_chan_close() { - let (tx, rx) = channel::<i32>(); - drop(tx); - assert_eq!(rx.recv(), Err(RecvError)); - } - - #[test] - fn oneshot_single_thread_send_then_recv() { - let (tx, rx) = channel::<Box<i32>>(); - tx.send(Box::new(10)).unwrap(); - assert!(*rx.recv().unwrap() == 10); - } - - #[test] - fn oneshot_single_thread_try_send_open() { - let (tx, rx) = channel::<i32>(); - assert!(tx.send(10).is_ok()); - assert!(rx.recv().unwrap() == 10); - } - - #[test] - fn oneshot_single_thread_try_send_closed() { - let (tx, rx) = channel::<i32>(); - drop(rx); - assert!(tx.send(10).is_err()); - } - - #[test] - fn oneshot_single_thread_try_recv_open() { - let (tx, rx) = channel::<i32>(); - tx.send(10).unwrap(); - assert!(rx.recv() == Ok(10)); - } - - #[test] - fn oneshot_single_thread_try_recv_closed() { - let (tx, rx) = channel::<i32>(); - drop(tx); - assert!(rx.recv().is_err()); - } - - #[test] - fn oneshot_single_thread_peek_data() { - let (tx, rx) = channel::<i32>(); - assert_eq!(rx.try_recv(), Err(TryRecvError::Empty)); - tx.send(10).unwrap(); - assert_eq!(rx.try_recv(), Ok(10)); - } - - #[test] - fn oneshot_single_thread_peek_close() { - let (tx, rx) = channel::<i32>(); - drop(tx); - assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected)); - assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected)); - } - - #[test] - fn oneshot_single_thread_peek_open() { - let (_tx, rx) = channel::<i32>(); - assert_eq!(rx.try_recv(), Err(TryRecvError::Empty)); - } - - #[test] - fn oneshot_multi_task_recv_then_send() { - let (tx, rx) = channel::<Box<i32>>(); - let t = thread::spawn(move || { - assert!(*rx.recv().unwrap() == 10); - }); - - tx.send(Box::new(10)).unwrap(); - t.join().unwrap(); - } - - #[test] - fn oneshot_multi_task_recv_then_close() { - let (tx, rx) = channel::<Box<i32>>(); - let t = thread::spawn(move || { - drop(tx); - }); - thread::spawn(move || { - assert_eq!(rx.recv(), Err(RecvError)); - }) - .join() - .unwrap(); - t.join().unwrap(); - } - - #[test] - fn oneshot_multi_thread_close_stress() { - let stress_factor = stress_factor(); - let mut ts = Vec::with_capacity(stress_factor); - for _ in 0..stress_factor { - let (tx, rx) = channel::<i32>(); - let t = thread::spawn(move || { - drop(rx); - }); - ts.push(t); - drop(tx); - } - for t in ts { - t.join().unwrap(); - } - } - - #[test] - fn oneshot_multi_thread_send_close_stress() { - let stress_factor = stress_factor(); - let mut ts = Vec::with_capacity(2 * stress_factor); - for _ in 0..stress_factor { - let (tx, rx) = channel::<i32>(); - let t = thread::spawn(move || { - drop(rx); - }); - ts.push(t); - thread::spawn(move || { - let _ = tx.send(1); - }) - .join() - .unwrap(); - } - for t in ts { - t.join().unwrap(); - } - } - - #[test] - fn oneshot_multi_thread_recv_close_stress() { - let stress_factor = stress_factor(); - let mut ts = Vec::with_capacity(2 * stress_factor); - for _ in 0..stress_factor { - let (tx, rx) = channel::<i32>(); - let t = thread::spawn(move || { - thread::spawn(move || { - assert_eq!(rx.recv(), Err(RecvError)); - }) - .join() - .unwrap(); - }); - ts.push(t); - let t2 = thread::spawn(move || { - let t = thread::spawn(move || { - drop(tx); - }); - t.join().unwrap(); - }); - ts.push(t2); - } - for t in ts { - t.join().unwrap(); - } - } - - #[test] - fn oneshot_multi_thread_send_recv_stress() { - let stress_factor = stress_factor(); - let mut ts = Vec::with_capacity(stress_factor); - for _ in 0..stress_factor { - let (tx, rx) = channel::<Box<isize>>(); - let t = thread::spawn(move || { - tx.send(Box::new(10)).unwrap(); - }); - ts.push(t); - assert!(*rx.recv().unwrap() == 10); - } - for t in ts { - t.join().unwrap(); - } - } - - #[test] - fn stream_send_recv_stress() { - let stress_factor = stress_factor(); - let mut ts = Vec::with_capacity(2 * stress_factor); - for _ in 0..stress_factor { - let (tx, rx) = channel(); - - if let Some(t) = send(tx, 0) { - ts.push(t); - } - if let Some(t2) = recv(rx, 0) { - ts.push(t2); - } - - fn send(tx: Sender<Box<i32>>, i: i32) -> Option<JoinHandle<()>> { - if i == 10 { - return None; - } - - Some(thread::spawn(move || { - tx.send(Box::new(i)).unwrap(); - send(tx, i + 1); - })) - } - - fn recv(rx: Receiver<Box<i32>>, i: i32) -> Option<JoinHandle<()>> { - if i == 10 { - return None; - } - - Some(thread::spawn(move || { - assert!(*rx.recv().unwrap() == i); - recv(rx, i + 1); - })) - } - } - for t in ts { - t.join().unwrap(); - } - } - - #[test] - fn oneshot_single_thread_recv_timeout() { - let (tx, rx) = channel(); - tx.send(()).unwrap(); - assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(())); - assert_eq!( - rx.recv_timeout(Duration::from_millis(1)), - Err(RecvTimeoutError::Timeout) - ); - tx.send(()).unwrap(); - assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(())); - } - - #[test] - fn stress_recv_timeout_two_threads() { - let (tx, rx) = channel(); - let stress = stress_factor() + 100; - let timeout = Duration::from_millis(100); - - let t = thread::spawn(move || { - for i in 0..stress { - if i % 2 == 0 { - thread::sleep(timeout * 2); - } - tx.send(1usize).unwrap(); - } - }); - - let mut recv_count = 0; - loop { - match rx.recv_timeout(timeout) { - Ok(n) => { - assert_eq!(n, 1usize); - recv_count += 1; - } - Err(RecvTimeoutError::Timeout) => continue, - Err(RecvTimeoutError::Disconnected) => break, - } - } - - assert_eq!(recv_count, stress); - t.join().unwrap() - } - - #[test] - fn recv_timeout_upgrade() { - let (tx, rx) = channel::<()>(); - let timeout = Duration::from_millis(1); - let _tx_clone = tx.clone(); - - let start = Instant::now(); - assert_eq!(rx.recv_timeout(timeout), Err(RecvTimeoutError::Timeout)); - assert!(Instant::now() >= start + timeout); - } - - #[test] - fn stress_recv_timeout_shared() { - let (tx, rx) = channel(); - let stress = stress_factor() + 100; - - let mut ts = Vec::with_capacity(stress); - for i in 0..stress { - let tx = tx.clone(); - let t = thread::spawn(move || { - thread::sleep(Duration::from_millis(i as u64 * 10)); - tx.send(1usize).unwrap(); - }); - ts.push(t); - } - - drop(tx); - - let mut recv_count = 0; - loop { - match rx.recv_timeout(Duration::from_millis(10)) { - Ok(n) => { - assert_eq!(n, 1usize); - recv_count += 1; - } - Err(RecvTimeoutError::Timeout) => continue, - Err(RecvTimeoutError::Disconnected) => break, - } - } - - assert_eq!(recv_count, stress); - for t in ts { - t.join().unwrap(); - } - } - - #[test] - fn recv_a_lot() { - // Regression test that we don't run out of stack in scheduler context - let (tx, rx) = channel(); - for _ in 0..10000 { - tx.send(()).unwrap(); - } - for _ in 0..10000 { - rx.recv().unwrap(); - } - } - - #[test] - fn shared_recv_timeout() { - let (tx, rx) = channel(); - let total = 5; - let mut ts = Vec::with_capacity(total); - for _ in 0..total { - let tx = tx.clone(); - let t = thread::spawn(move || { - tx.send(()).unwrap(); - }); - ts.push(t); - } - - for _ in 0..total { - rx.recv().unwrap(); - } - - assert_eq!( - rx.recv_timeout(Duration::from_millis(1)), - Err(RecvTimeoutError::Timeout) - ); - tx.send(()).unwrap(); - assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(())); - for t in ts { - t.join().unwrap(); - } - } - - #[test] - fn shared_chan_stress() { - let (tx, rx) = channel(); - let total = stress_factor() + 100; - let mut ts = Vec::with_capacity(total); - for _ in 0..total { - let tx = tx.clone(); - let t = thread::spawn(move || { - tx.send(()).unwrap(); - }); - ts.push(t); - } - - for _ in 0..total { - rx.recv().unwrap(); - } - for t in ts { - t.join().unwrap(); - } - } - - #[test] - fn test_nested_recv_iter() { - let (tx, rx) = channel::<i32>(); - let (total_tx, total_rx) = channel::<i32>(); - - let t = thread::spawn(move || { - let mut acc = 0; - for x in rx.iter() { - acc += x; - } - total_tx.send(acc).unwrap(); - }); - - tx.send(3).unwrap(); - tx.send(1).unwrap(); - tx.send(2).unwrap(); - drop(tx); - assert_eq!(total_rx.recv().unwrap(), 6); - t.join().unwrap(); - } - - #[test] - fn test_recv_iter_break() { - let (tx, rx) = channel::<i32>(); - let (count_tx, count_rx) = channel(); - - let t = thread::spawn(move || { - let mut count = 0; - for x in rx.iter() { - if count >= 3 { - break; - } else { - count += x; - } - } - count_tx.send(count).unwrap(); - }); - - tx.send(2).unwrap(); - tx.send(2).unwrap(); - tx.send(2).unwrap(); - let _ = tx.send(2); - drop(tx); - assert_eq!(count_rx.recv().unwrap(), 4); - t.join().unwrap(); - } - - #[test] - fn test_recv_try_iter() { - let (request_tx, request_rx) = channel(); - let (response_tx, response_rx) = channel(); - - // Request `x`s until we have `6`. - let t = thread::spawn(move || { - let mut count = 0; - loop { - for x in response_rx.try_iter() { - count += x; - if count == 6 { - return count; - } - } - request_tx.send(()).unwrap(); - } - }); - - for _ in request_rx.iter() { - if response_tx.send(2).is_err() { - break; - } - } - - assert_eq!(t.join().unwrap(), 6); - } - - #[test] - fn test_recv_into_iter_owned() { - let mut iter = { - let (tx, rx) = channel::<i32>(); - tx.send(1).unwrap(); - tx.send(2).unwrap(); - - rx.into_iter() - }; - assert_eq!(iter.next().unwrap(), 1); - assert_eq!(iter.next().unwrap(), 2); - assert_eq!(iter.next().is_none(), true); - } - - #[test] - fn test_recv_into_iter_borrowed() { - let (tx, rx) = channel::<i32>(); - tx.send(1).unwrap(); - tx.send(2).unwrap(); - drop(tx); - let mut iter = (&rx).into_iter(); - assert_eq!(iter.next().unwrap(), 1); - assert_eq!(iter.next().unwrap(), 2); - assert_eq!(iter.next().is_none(), true); - } - - #[test] - fn try_recv_states() { - let (tx1, rx1) = channel::<i32>(); - let (tx2, rx2) = channel::<()>(); - let (tx3, rx3) = channel::<()>(); - let t = thread::spawn(move || { - rx2.recv().unwrap(); - tx1.send(1).unwrap(); - tx3.send(()).unwrap(); - rx2.recv().unwrap(); - drop(tx1); - tx3.send(()).unwrap(); - }); - - assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty)); - tx2.send(()).unwrap(); - rx3.recv().unwrap(); - assert_eq!(rx1.try_recv(), Ok(1)); - assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty)); - tx2.send(()).unwrap(); - rx3.recv().unwrap(); - assert_eq!(rx1.try_recv(), Err(TryRecvError::Disconnected)); - t.join().unwrap(); - } - - // This bug used to end up in a livelock inside of the Receiver destructor - // because the internal state of the Shared packet was corrupted - #[test] - fn destroy_upgraded_shared_port_when_sender_still_active() { - let (tx, rx) = channel(); - let (tx2, rx2) = channel(); - let t = thread::spawn(move || { - rx.recv().unwrap(); // wait on a oneshot - drop(rx); // destroy a shared - tx2.send(()).unwrap(); - }); - // make sure the other thread has gone to sleep - for _ in 0..5000 { - thread::yield_now(); - } - - // upgrade to a shared chan and send a message - let tx2 = tx.clone(); - drop(tx); - tx2.send(()).unwrap(); - - // wait for the child thread to exit before we exit - rx2.recv().unwrap(); - t.join().unwrap(); - } - - #[test] - fn issue_32114() { - let (tx, _) = channel(); - let _ = tx.send(123); - assert_eq!(tx.send(123), Err(SendError(123))); - } -} - -// Source: https://github.com/rust-lang/rust/blob/master/src/libstd/sync/mpsc/mod.rs -mod sync_channel_tests { - use super::*; - - use std::env; - use std::thread; - use std::time::Duration; - - pub fn stress_factor() -> usize { - match env::var("RUST_TEST_STRESS") { - Ok(val) => val.parse().unwrap(), - Err(..) => 1, - } - } - - #[test] - fn smoke() { - let (tx, rx) = sync_channel::<i32>(1); - tx.send(1).unwrap(); - assert_eq!(rx.recv().unwrap(), 1); - } - - #[test] - fn drop_full() { - let (tx, _rx) = sync_channel::<Box<isize>>(1); - tx.send(Box::new(1)).unwrap(); - } - - #[test] - fn smoke_shared() { - let (tx, rx) = sync_channel::<i32>(1); - tx.send(1).unwrap(); - assert_eq!(rx.recv().unwrap(), 1); - let tx = tx.clone(); - tx.send(1).unwrap(); - assert_eq!(rx.recv().unwrap(), 1); - } - - #[test] - fn recv_timeout() { - let (tx, rx) = sync_channel::<i32>(1); - assert_eq!( - rx.recv_timeout(Duration::from_millis(1)), - Err(RecvTimeoutError::Timeout) - ); - tx.send(1).unwrap(); - assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(1)); - } - - #[test] - fn smoke_threads() { - let (tx, rx) = sync_channel::<i32>(0); - let t = thread::spawn(move || { - tx.send(1).unwrap(); - }); - assert_eq!(rx.recv().unwrap(), 1); - t.join().unwrap(); - } - - #[test] - fn smoke_port_gone() { - let (tx, rx) = sync_channel::<i32>(0); - drop(rx); - assert!(tx.send(1).is_err()); - } - - #[test] - fn smoke_shared_port_gone2() { - let (tx, rx) = sync_channel::<i32>(0); - drop(rx); - let tx2 = tx.clone(); - drop(tx); - assert!(tx2.send(1).is_err()); - } - - #[test] - fn port_gone_concurrent() { - let (tx, rx) = sync_channel::<i32>(0); - let t = thread::spawn(move || { - rx.recv().unwrap(); - }); - while tx.send(1).is_ok() {} - t.join().unwrap(); - } - - #[test] - fn port_gone_concurrent_shared() { - let (tx, rx) = sync_channel::<i32>(0); - let tx2 = tx.clone(); - let t = thread::spawn(move || { - rx.recv().unwrap(); - }); - while tx.send(1).is_ok() && tx2.send(1).is_ok() {} - t.join().unwrap(); - } - - #[test] - fn smoke_chan_gone() { - let (tx, rx) = sync_channel::<i32>(0); - drop(tx); - assert!(rx.recv().is_err()); - } - - #[test] - fn smoke_chan_gone_shared() { - let (tx, rx) = sync_channel::<()>(0); - let tx2 = tx.clone(); - drop(tx); - drop(tx2); - assert!(rx.recv().is_err()); - } - - #[test] - fn chan_gone_concurrent() { - let (tx, rx) = sync_channel::<i32>(0); - let t = thread::spawn(move || { - tx.send(1).unwrap(); - tx.send(1).unwrap(); - }); - while rx.recv().is_ok() {} - t.join().unwrap(); - } - - #[test] - fn stress() { - let (tx, rx) = sync_channel::<i32>(0); - let t = thread::spawn(move || { - for _ in 0..10000 { - tx.send(1).unwrap(); - } - }); - for _ in 0..10000 { - assert_eq!(rx.recv().unwrap(), 1); - } - t.join().unwrap(); - } - - #[test] - fn stress_recv_timeout_two_threads() { - let (tx, rx) = sync_channel::<i32>(0); - - let t = thread::spawn(move || { - for _ in 0..10000 { - tx.send(1).unwrap(); - } - }); - - let mut recv_count = 0; - loop { - match rx.recv_timeout(Duration::from_millis(1)) { - Ok(v) => { - assert_eq!(v, 1); - recv_count += 1; - } - Err(RecvTimeoutError::Timeout) => continue, - Err(RecvTimeoutError::Disconnected) => break, - } - } - - assert_eq!(recv_count, 10000); - t.join().unwrap(); - } - - #[test] - fn stress_recv_timeout_shared() { - const AMT: u32 = 1000; - const NTHREADS: u32 = 8; - let (tx, rx) = sync_channel::<i32>(0); - let (dtx, drx) = sync_channel::<()>(0); - - let t = thread::spawn(move || { - let mut recv_count = 0; - loop { - match rx.recv_timeout(Duration::from_millis(10)) { - Ok(v) => { - assert_eq!(v, 1); - recv_count += 1; - } - Err(RecvTimeoutError::Timeout) => continue, - Err(RecvTimeoutError::Disconnected) => break, - } - } - - assert_eq!(recv_count, AMT * NTHREADS); - assert!(rx.try_recv().is_err()); - - dtx.send(()).unwrap(); - }); - - let mut ts = Vec::with_capacity(NTHREADS as usize); - for _ in 0..NTHREADS { - let tx = tx.clone(); - let t = thread::spawn(move || { - for _ in 0..AMT { - tx.send(1).unwrap(); - } - }); - ts.push(t); - } - - drop(tx); - - drx.recv().unwrap(); - for t in ts { - t.join().unwrap(); - } - t.join().unwrap(); - } - - #[test] - fn stress_shared() { - const AMT: u32 = 1000; - const NTHREADS: u32 = 8; - let (tx, rx) = sync_channel::<i32>(0); - let (dtx, drx) = sync_channel::<()>(0); - - let t = thread::spawn(move || { - for _ in 0..AMT * NTHREADS { - assert_eq!(rx.recv().unwrap(), 1); - } - match rx.try_recv() { - Ok(..) => panic!(), - _ => {} - } - dtx.send(()).unwrap(); - }); - - let mut ts = Vec::with_capacity(NTHREADS as usize); - for _ in 0..NTHREADS { - let tx = tx.clone(); - let t = thread::spawn(move || { - for _ in 0..AMT { - tx.send(1).unwrap(); - } - }); - ts.push(t); - } - drop(tx); - drx.recv().unwrap(); - for t in ts { - t.join().unwrap(); - } - t.join().unwrap(); - } - - #[test] - fn oneshot_single_thread_close_port_first() { - // Simple test of closing without sending - let (_tx, rx) = sync_channel::<i32>(0); - drop(rx); - } - - #[test] - fn oneshot_single_thread_close_chan_first() { - // Simple test of closing without sending - let (tx, _rx) = sync_channel::<i32>(0); - drop(tx); - } - - #[test] - fn oneshot_single_thread_send_port_close() { - // Testing that the sender cleans up the payload if receiver is closed - let (tx, rx) = sync_channel::<Box<i32>>(0); - drop(rx); - assert!(tx.send(Box::new(0)).is_err()); - } - - #[test] - fn oneshot_single_thread_recv_chan_close() { - let (tx, rx) = sync_channel::<i32>(0); - drop(tx); - assert_eq!(rx.recv(), Err(RecvError)); - } - - #[test] - fn oneshot_single_thread_send_then_recv() { - let (tx, rx) = sync_channel::<Box<i32>>(1); - tx.send(Box::new(10)).unwrap(); - assert!(*rx.recv().unwrap() == 10); - } - - #[test] - fn oneshot_single_thread_try_send_open() { - let (tx, rx) = sync_channel::<i32>(1); - assert_eq!(tx.try_send(10), Ok(())); - assert!(rx.recv().unwrap() == 10); - } - - #[test] - fn oneshot_single_thread_try_send_closed() { - let (tx, rx) = sync_channel::<i32>(0); - drop(rx); - assert_eq!(tx.try_send(10), Err(TrySendError::Disconnected(10))); - } - - #[test] - fn oneshot_single_thread_try_send_closed2() { - let (tx, _rx) = sync_channel::<i32>(0); - assert_eq!(tx.try_send(10), Err(TrySendError::Full(10))); - } - - #[test] - fn oneshot_single_thread_try_recv_open() { - let (tx, rx) = sync_channel::<i32>(1); - tx.send(10).unwrap(); - assert!(rx.recv() == Ok(10)); - } - - #[test] - fn oneshot_single_thread_try_recv_closed() { - let (tx, rx) = sync_channel::<i32>(0); - drop(tx); - assert!(rx.recv().is_err()); - } - - #[test] - fn oneshot_single_thread_try_recv_closed_with_data() { - let (tx, rx) = sync_channel::<i32>(1); - tx.send(10).unwrap(); - drop(tx); - assert_eq!(rx.try_recv(), Ok(10)); - assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected)); - } - - #[test] - fn oneshot_single_thread_peek_data() { - let (tx, rx) = sync_channel::<i32>(1); - assert_eq!(rx.try_recv(), Err(TryRecvError::Empty)); - tx.send(10).unwrap(); - assert_eq!(rx.try_recv(), Ok(10)); - } - - #[test] - fn oneshot_single_thread_peek_close() { - let (tx, rx) = sync_channel::<i32>(0); - drop(tx); - assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected)); - assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected)); - } - - #[test] - fn oneshot_single_thread_peek_open() { - let (_tx, rx) = sync_channel::<i32>(0); - assert_eq!(rx.try_recv(), Err(TryRecvError::Empty)); - } - - #[test] - fn oneshot_multi_task_recv_then_send() { - let (tx, rx) = sync_channel::<Box<i32>>(0); - let t = thread::spawn(move || { - assert!(*rx.recv().unwrap() == 10); - }); - - tx.send(Box::new(10)).unwrap(); - t.join().unwrap(); - } - - #[test] - fn oneshot_multi_task_recv_then_close() { - let (tx, rx) = sync_channel::<Box<i32>>(0); - let t = thread::spawn(move || { - drop(tx); - }); - thread::spawn(move || { - assert_eq!(rx.recv(), Err(RecvError)); - }) - .join() - .unwrap(); - t.join().unwrap(); - } - - #[test] - fn oneshot_multi_thread_close_stress() { - let stress_factor = stress_factor(); - let mut ts = Vec::with_capacity(stress_factor); - for _ in 0..stress_factor { - let (tx, rx) = sync_channel::<i32>(0); - let t = thread::spawn(move || { - drop(rx); - }); - ts.push(t); - drop(tx); - } - for t in ts { - t.join().unwrap(); - } - } - - #[test] - fn oneshot_multi_thread_send_close_stress() { - let stress_factor = stress_factor(); - let mut ts = Vec::with_capacity(stress_factor); - for _ in 0..stress_factor { - let (tx, rx) = sync_channel::<i32>(0); - let t = thread::spawn(move || { - drop(rx); - }); - ts.push(t); - thread::spawn(move || { - let _ = tx.send(1); - }) - .join() - .unwrap(); - } - for t in ts { - t.join().unwrap(); - } - } - - #[test] - fn oneshot_multi_thread_recv_close_stress() { - let stress_factor = stress_factor(); - let mut ts = Vec::with_capacity(2 * stress_factor); - for _ in 0..stress_factor { - let (tx, rx) = sync_channel::<i32>(0); - let t = thread::spawn(move || { - thread::spawn(move || { - assert_eq!(rx.recv(), Err(RecvError)); - }) - .join() - .unwrap(); - }); - ts.push(t); - let t2 = thread::spawn(move || { - thread::spawn(move || { - drop(tx); - }); - }); - ts.push(t2); - } - for t in ts { - t.join().unwrap(); - } - } - - #[test] - fn oneshot_multi_thread_send_recv_stress() { - let stress_factor = stress_factor(); - let mut ts = Vec::with_capacity(stress_factor); - for _ in 0..stress_factor { - let (tx, rx) = sync_channel::<Box<i32>>(0); - let t = thread::spawn(move || { - tx.send(Box::new(10)).unwrap(); - }); - ts.push(t); - assert!(*rx.recv().unwrap() == 10); - } - for t in ts { - t.join().unwrap(); - } - } - - #[test] - fn stream_send_recv_stress() { - let stress_factor = stress_factor(); - let mut ts = Vec::with_capacity(2 * stress_factor); - for _ in 0..stress_factor { - let (tx, rx) = sync_channel::<Box<i32>>(0); - - if let Some(t) = send(tx, 0) { - ts.push(t); - } - if let Some(t) = recv(rx, 0) { - ts.push(t); - } - - fn send(tx: SyncSender<Box<i32>>, i: i32) -> Option<JoinHandle<()>> { - if i == 10 { - return None; - } - - Some(thread::spawn(move || { - tx.send(Box::new(i)).unwrap(); - send(tx, i + 1); - })) - } - - fn recv(rx: Receiver<Box<i32>>, i: i32) -> Option<JoinHandle<()>> { - if i == 10 { - return None; - } - - Some(thread::spawn(move || { - assert!(*rx.recv().unwrap() == i); - recv(rx, i + 1); - })) - } - } - for t in ts { - t.join().unwrap(); - } - } - - #[test] - fn recv_a_lot() { - // Regression test that we don't run out of stack in scheduler context - let (tx, rx) = sync_channel(10000); - for _ in 0..10000 { - tx.send(()).unwrap(); - } - for _ in 0..10000 { - rx.recv().unwrap(); - } - } - - #[test] - fn shared_chan_stress() { - let (tx, rx) = sync_channel(0); - let total = stress_factor() + 100; - let mut ts = Vec::with_capacity(total); - for _ in 0..total { - let tx = tx.clone(); - let t = thread::spawn(move || { - tx.send(()).unwrap(); - }); - ts.push(t); - } - - for _ in 0..total { - rx.recv().unwrap(); - } - for t in ts { - t.join().unwrap(); - } - } - - #[test] - fn test_nested_recv_iter() { - let (tx, rx) = sync_channel::<i32>(0); - let (total_tx, total_rx) = sync_channel::<i32>(0); - - let t = thread::spawn(move || { - let mut acc = 0; - for x in rx.iter() { - acc += x; - } - total_tx.send(acc).unwrap(); - }); - - tx.send(3).unwrap(); - tx.send(1).unwrap(); - tx.send(2).unwrap(); - drop(tx); - assert_eq!(total_rx.recv().unwrap(), 6); - t.join().unwrap(); - } - - #[test] - fn test_recv_iter_break() { - let (tx, rx) = sync_channel::<i32>(0); - let (count_tx, count_rx) = sync_channel(0); - - let t = thread::spawn(move || { - let mut count = 0; - for x in rx.iter() { - if count >= 3 { - break; - } else { - count += x; - } - } - count_tx.send(count).unwrap(); - }); - - tx.send(2).unwrap(); - tx.send(2).unwrap(); - tx.send(2).unwrap(); - let _ = tx.try_send(2); - drop(tx); - assert_eq!(count_rx.recv().unwrap(), 4); - t.join().unwrap(); - } - - #[test] - fn try_recv_states() { - let (tx1, rx1) = sync_channel::<i32>(1); - let (tx2, rx2) = sync_channel::<()>(1); - let (tx3, rx3) = sync_channel::<()>(1); - let t = thread::spawn(move || { - rx2.recv().unwrap(); - tx1.send(1).unwrap(); - tx3.send(()).unwrap(); - rx2.recv().unwrap(); - drop(tx1); - tx3.send(()).unwrap(); - }); - - assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty)); - tx2.send(()).unwrap(); - rx3.recv().unwrap(); - assert_eq!(rx1.try_recv(), Ok(1)); - assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty)); - tx2.send(()).unwrap(); - rx3.recv().unwrap(); - assert_eq!(rx1.try_recv(), Err(TryRecvError::Disconnected)); - t.join().unwrap(); - } - - // This bug used to end up in a livelock inside of the Receiver destructor - // because the internal state of the Shared packet was corrupted - #[test] - fn destroy_upgraded_shared_port_when_sender_still_active() { - let (tx, rx) = sync_channel::<()>(0); - let (tx2, rx2) = sync_channel::<()>(0); - let t = thread::spawn(move || { - rx.recv().unwrap(); // wait on a oneshot - drop(rx); // destroy a shared - tx2.send(()).unwrap(); - }); - // make sure the other thread has gone to sleep - for _ in 0..5000 { - thread::yield_now(); - } - - // upgrade to a shared chan and send a message - let tx2 = tx.clone(); - drop(tx); - tx2.send(()).unwrap(); - - // wait for the child thread to exit before we exit - rx2.recv().unwrap(); - t.join().unwrap(); - } - - #[test] - fn send1() { - let (tx, rx) = sync_channel::<i32>(0); - let t = thread::spawn(move || { - rx.recv().unwrap(); - }); - assert_eq!(tx.send(1), Ok(())); - t.join().unwrap(); - } - - #[test] - fn send2() { - let (tx, rx) = sync_channel::<i32>(0); - let t = thread::spawn(move || { - drop(rx); - }); - assert!(tx.send(1).is_err()); - t.join().unwrap(); - } - - #[test] - fn send3() { - let (tx, rx) = sync_channel::<i32>(1); - assert_eq!(tx.send(1), Ok(())); - let t = thread::spawn(move || { - drop(rx); - }); - assert!(tx.send(1).is_err()); - t.join().unwrap(); - } - - #[test] - fn send4() { - let (tx, rx) = sync_channel::<i32>(0); - let tx2 = tx.clone(); - let (done, donerx) = channel(); - let done2 = done.clone(); - let t = thread::spawn(move || { - assert!(tx.send(1).is_err()); - done.send(()).unwrap(); - }); - let t2 = thread::spawn(move || { - assert!(tx2.send(2).is_err()); - done2.send(()).unwrap(); - }); - drop(rx); - donerx.recv().unwrap(); - donerx.recv().unwrap(); - t.join().unwrap(); - t2.join().unwrap(); - } - - #[test] - fn try_send1() { - let (tx, _rx) = sync_channel::<i32>(0); - assert_eq!(tx.try_send(1), Err(TrySendError::Full(1))); - } - - #[test] - fn try_send2() { - let (tx, _rx) = sync_channel::<i32>(1); - assert_eq!(tx.try_send(1), Ok(())); - assert_eq!(tx.try_send(1), Err(TrySendError::Full(1))); - } - - #[test] - fn try_send3() { - let (tx, rx) = sync_channel::<i32>(1); - assert_eq!(tx.try_send(1), Ok(())); - drop(rx); - assert_eq!(tx.try_send(1), Err(TrySendError::Disconnected(1))); - } - - #[test] - fn issue_15761() { - fn repro() { - let (tx1, rx1) = sync_channel::<()>(3); - let (tx2, rx2) = sync_channel::<()>(3); - - let _t = thread::spawn(move || { - rx1.recv().unwrap(); - tx2.try_send(()).unwrap(); - }); - - tx1.try_send(()).unwrap(); - rx2.recv().unwrap(); - } - - for _ in 0..100 { - repro() - } - } -} - -// Source: https://github.com/rust-lang/rust/blob/master/src/libstd/sync/mpsc/select.rs -mod select_tests { - use super::*; - - use std::thread; - - #[test] - fn smoke() { - let (tx1, rx1) = channel::<i32>(); - let (tx2, rx2) = channel::<i32>(); - tx1.send(1).unwrap(); - select! { - foo = rx1.recv() => { assert_eq!(foo.unwrap(), 1); }, - _bar = rx2.recv() => { panic!() } - } - tx2.send(2).unwrap(); - select! { - _foo = rx1.recv() => { panic!() }, - bar = rx2.recv() => { assert_eq!(bar.unwrap(), 2) } - } - drop(tx1); - select! { - foo = rx1.recv() => { assert!(foo.is_err()); }, - _bar = rx2.recv() => { panic!() } - } - drop(tx2); - select! { - bar = rx2.recv() => { assert!(bar.is_err()); } - } - } - - #[test] - fn smoke2() { - let (_tx1, rx1) = channel::<i32>(); - let (_tx2, rx2) = channel::<i32>(); - let (_tx3, rx3) = channel::<i32>(); - let (_tx4, rx4) = channel::<i32>(); - let (tx5, rx5) = channel::<i32>(); - tx5.send(4).unwrap(); - select! { - _foo = rx1.recv() => { panic!("1") }, - _foo = rx2.recv() => { panic!("2") }, - _foo = rx3.recv() => { panic!("3") }, - _foo = rx4.recv() => { panic!("4") }, - foo = rx5.recv() => { assert_eq!(foo.unwrap(), 4); } - } - } - - #[test] - fn closed() { - let (_tx1, rx1) = channel::<i32>(); - let (tx2, rx2) = channel::<i32>(); - drop(tx2); - - select! { - _a1 = rx1.recv() => { panic!() }, - a2 = rx2.recv() => { assert!(a2.is_err()); } - } - } - - #[test] - fn unblocks() { - let (tx1, rx1) = channel::<i32>(); - let (_tx2, rx2) = channel::<i32>(); - let (tx3, rx3) = channel::<i32>(); - - let t = thread::spawn(move || { - for _ in 0..20 { - thread::yield_now(); - } - tx1.send(1).unwrap(); - rx3.recv().unwrap(); - for _ in 0..20 { - thread::yield_now(); - } - }); - - select! { - a = rx1.recv() => { assert_eq!(a.unwrap(), 1); }, - _b = rx2.recv() => { panic!() } - } - tx3.send(1).unwrap(); - select! { - a = rx1.recv() => { assert!(a.is_err()) }, - _b = rx2.recv() => { panic!() } - } - t.join().unwrap(); - } - - #[test] - fn both_ready() { - let (tx1, rx1) = channel::<i32>(); - let (tx2, rx2) = channel::<i32>(); - let (tx3, rx3) = channel::<()>(); - - let t = thread::spawn(move || { - for _ in 0..20 { - thread::yield_now(); - } - tx1.send(1).unwrap(); - tx2.send(2).unwrap(); - rx3.recv().unwrap(); - }); - - select! { - a = rx1.recv() => { assert_eq!(a.unwrap(), 1); }, - a = rx2.recv() => { assert_eq!(a.unwrap(), 2); } - } - select! { - a = rx1.recv() => { assert_eq!(a.unwrap(), 1); }, - a = rx2.recv() => { assert_eq!(a.unwrap(), 2); } - } - assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty)); - assert_eq!(rx2.try_recv(), Err(TryRecvError::Empty)); - tx3.send(()).unwrap(); - t.join().unwrap(); - } - - #[test] - fn stress() { - const AMT: i32 = 10000; - let (tx1, rx1) = channel::<i32>(); - let (tx2, rx2) = channel::<i32>(); - let (tx3, rx3) = channel::<()>(); - - let t = thread::spawn(move || { - for i in 0..AMT { - if i % 2 == 0 { - tx1.send(i).unwrap(); - } else { - tx2.send(i).unwrap(); - } - rx3.recv().unwrap(); - } - }); - - for i in 0..AMT { - select! { - i1 = rx1.recv() => { assert!(i % 2 == 0 && i == i1.unwrap()); }, - i2 = rx2.recv() => { assert!(i % 2 == 1 && i == i2.unwrap()); } - } - tx3.send(()).unwrap(); - } - t.join().unwrap(); - } - - #[allow(unused_must_use)] - #[test] - fn cloning() { - let (tx1, rx1) = channel::<i32>(); - let (_tx2, rx2) = channel::<i32>(); - let (tx3, rx3) = channel::<()>(); - - let t = thread::spawn(move || { - rx3.recv().unwrap(); - tx1.clone(); - assert_eq!(rx3.try_recv(), Err(TryRecvError::Empty)); - tx1.send(2).unwrap(); - rx3.recv().unwrap(); - }); - - tx3.send(()).unwrap(); - select! { - _i1 = rx1.recv() => {}, - _i2 = rx2.recv() => panic!() - } - tx3.send(()).unwrap(); - t.join().unwrap(); - } - - #[allow(unused_must_use)] - #[test] - fn cloning2() { - let (tx1, rx1) = channel::<i32>(); - let (_tx2, rx2) = channel::<i32>(); - let (tx3, rx3) = channel::<()>(); - - let t = thread::spawn(move || { - rx3.recv().unwrap(); - tx1.clone(); - assert_eq!(rx3.try_recv(), Err(TryRecvError::Empty)); - tx1.send(2).unwrap(); - rx3.recv().unwrap(); - }); - - tx3.send(()).unwrap(); - select! { - _i1 = rx1.recv() => {}, - _i2 = rx2.recv() => panic!() - } - tx3.send(()).unwrap(); - t.join().unwrap(); - } - - #[test] - fn cloning3() { - let (tx1, rx1) = channel::<()>(); - let (tx2, rx2) = channel::<()>(); - let (tx3, rx3) = channel::<()>(); - let t = thread::spawn(move || { - select! { - _ = rx1.recv() => panic!(), - _ = rx2.recv() => {} - } - tx3.send(()).unwrap(); - }); - - for _ in 0..1000 { - thread::yield_now(); - } - drop(tx1.clone()); - tx2.send(()).unwrap(); - rx3.recv().unwrap(); - t.join().unwrap(); - } - - #[test] - fn preflight1() { - let (tx, rx) = channel(); - tx.send(()).unwrap(); - select! { - _n = rx.recv() => {} - } - } - - #[test] - fn preflight2() { - let (tx, rx) = channel(); - tx.send(()).unwrap(); - tx.send(()).unwrap(); - select! { - _n = rx.recv() => {} - } - } - - #[test] - fn preflight3() { - let (tx, rx) = channel(); - drop(tx.clone()); - tx.send(()).unwrap(); - select! { - _n = rx.recv() => {} - } - } - - #[test] - fn preflight4() { - let (tx, rx) = channel(); - tx.send(()).unwrap(); - select! { - _ = rx.recv() => {} - } - } - - #[test] - fn preflight5() { - let (tx, rx) = channel(); - tx.send(()).unwrap(); - tx.send(()).unwrap(); - select! { - _ = rx.recv() => {} - } - } - - #[test] - fn preflight6() { - let (tx, rx) = channel(); - drop(tx.clone()); - tx.send(()).unwrap(); - select! { - _ = rx.recv() => {} - } - } - - #[test] - fn preflight7() { - let (tx, rx) = channel::<()>(); - drop(tx); - select! { - _ = rx.recv() => {} - } - } - - #[test] - fn preflight8() { - let (tx, rx) = channel(); - tx.send(()).unwrap(); - drop(tx); - rx.recv().unwrap(); - select! { - _ = rx.recv() => {} - } - } - - #[test] - fn preflight9() { - let (tx, rx) = channel(); - drop(tx.clone()); - tx.send(()).unwrap(); - drop(tx); - rx.recv().unwrap(); - select! { - _ = rx.recv() => {} - } - } - - #[test] - fn oneshot_data_waiting() { - let (tx1, rx1) = channel(); - let (tx2, rx2) = channel(); - let t = thread::spawn(move || { - select! { - _n = rx1.recv() => {} - } - tx2.send(()).unwrap(); - }); - - for _ in 0..100 { - thread::yield_now() - } - tx1.send(()).unwrap(); - rx2.recv().unwrap(); - t.join().unwrap(); - } - - #[test] - fn stream_data_waiting() { - let (tx1, rx1) = channel(); - let (tx2, rx2) = channel(); - tx1.send(()).unwrap(); - tx1.send(()).unwrap(); - rx1.recv().unwrap(); - rx1.recv().unwrap(); - let t = thread::spawn(move || { - select! { - _n = rx1.recv() => {} - } - tx2.send(()).unwrap(); - }); - - for _ in 0..100 { - thread::yield_now() - } - tx1.send(()).unwrap(); - rx2.recv().unwrap(); - t.join().unwrap(); - } - - #[test] - fn shared_data_waiting() { - let (tx1, rx1) = channel(); - let (tx2, rx2) = channel(); - drop(tx1.clone()); - tx1.send(()).unwrap(); - rx1.recv().unwrap(); - let t = thread::spawn(move || { - select! { - _n = rx1.recv() => {} - } - tx2.send(()).unwrap(); - }); - - for _ in 0..100 { - thread::yield_now() - } - tx1.send(()).unwrap(); - rx2.recv().unwrap(); - t.join().unwrap(); - } - - #[test] - fn sync1() { - let (tx, rx) = sync_channel::<i32>(1); - tx.send(1).unwrap(); - select! { - n = rx.recv() => { assert_eq!(n.unwrap(), 1); } - } - } - - #[test] - fn sync2() { - let (tx, rx) = sync_channel::<i32>(0); - let t = thread::spawn(move || { - for _ in 0..100 { - thread::yield_now() - } - tx.send(1).unwrap(); - }); - select! { - n = rx.recv() => { assert_eq!(n.unwrap(), 1); } - } - t.join().unwrap(); - } - - #[test] - fn sync3() { - let (tx1, rx1) = sync_channel::<i32>(0); - let (tx2, rx2): (Sender<i32>, Receiver<i32>) = channel(); - let t = thread::spawn(move || { - tx1.send(1).unwrap(); - }); - let t2 = thread::spawn(move || { - tx2.send(2).unwrap(); - }); - select! { - n = rx1.recv() => { - let n = n.unwrap(); - assert_eq!(n, 1); - assert_eq!(rx2.recv().unwrap(), 2); - }, - n = rx2.recv() => { - let n = n.unwrap(); - assert_eq!(n, 2); - assert_eq!(rx1.recv().unwrap(), 1); - } - } - t.join().unwrap(); - t2.join().unwrap(); - } -} diff --git a/vendor/flume/tests/never.rs b/vendor/flume/tests/never.rs deleted file mode 100644 index 676903f..0000000 --- a/vendor/flume/tests/never.rs +++ /dev/null @@ -1,99 +0,0 @@ -// //! Tests for the never channel flavor. - -// #[macro_use] -// extern crate crossbeam_channel; -// extern crate rand; - -// use std::thread; -// use std::time::{Duration, Instant}; - -// use crossbeam_channel::{never, tick, unbounded}; - -// fn ms(ms: u64) -> Duration { -// Duration::from_millis(ms) -// } - -// #[test] -// fn smoke() { -// select! { -// recv(never::<i32>()) -> _ => panic!(), -// default => {} -// } -// } - -// #[test] -// fn optional() { -// let (s, r) = unbounded::<i32>(); -// s.send(1).unwrap(); -// s.send(2).unwrap(); - -// let mut r = Some(&r); -// select! { -// recv(r.unwrap_or(&never())) -> _ => {} -// default => panic!(), -// } - -// r = None; -// select! { -// recv(r.unwrap_or(&never())) -> _ => panic!(), -// default => {} -// } -// } - -// #[test] -// fn tick_n() { -// let mut r = tick(ms(100)); -// let mut step = 0; - -// loop { -// select! { -// recv(r) -> _ => step += 1, -// default(ms(500)) => break, -// } - -// if step == 10 { -// r = never(); -// } -// } - -// assert_eq!(step, 10); -// } - -// #[test] -// fn capacity() { -// let r = never::<i32>(); -// assert_eq!(r.capacity(), Some(0)); -// } - -// #[test] -// fn len_empty_full() { -// let r = never::<i32>(); -// assert_eq!(r.len(), 0); -// assert_eq!(r.is_empty(), true); -// assert_eq!(r.is_full(), true); -// } - -// #[test] -// fn try_recv() { -// let r = never::<i32>(); -// assert!(r.try_recv().is_err()); - -// thread::sleep(ms(100)); -// assert!(r.try_recv().is_err()); -// } - -// #[test] -// fn recv_timeout() { -// let start = Instant::now(); -// let r = never::<i32>(); - -// assert!(r.recv_timeout(ms(100)).is_err()); -// let now = Instant::now(); -// assert!(now - start >= ms(100)); -// assert!(now - start <= ms(150)); - -// assert!(r.recv_timeout(ms(100)).is_err()); -// let now = Instant::now(); -// assert!(now - start >= ms(200)); -// assert!(now - start <= ms(250)); -// } diff --git a/vendor/flume/tests/ready.rs b/vendor/flume/tests/ready.rs deleted file mode 100644 index 2f42d9a..0000000 --- a/vendor/flume/tests/ready.rs +++ /dev/null @@ -1,837 +0,0 @@ -// //! Tests for channel readiness using the `Select` struct. - -// extern crate crossbeam_channel; -// extern crate crossbeam_utils; - -// use std::any::Any; -// use std::cell::Cell; -// use std::thread; -// use std::time::{Duration, Instant}; - -// use crossbeam_channel::{after, bounded, tick, unbounded}; -// use crossbeam_channel::{Receiver, Select, TryRecvError, TrySendError}; -// use crossbeam_utils::thread::scope; - -// fn ms(ms: u64) -> Duration { -// Duration::from_millis(ms) -// } - -// #[test] -// fn smoke1() { -// let (s1, r1) = unbounded::<usize>(); -// let (s2, r2) = unbounded::<usize>(); - -// s1.send(1).unwrap(); - -// let mut sel = Select::new(); -// sel.recv(&r1); -// sel.recv(&r2); -// assert_eq!(sel.ready(), 0); -// assert_eq!(r1.try_recv(), Ok(1)); - -// s2.send(2).unwrap(); - -// let mut sel = Select::new(); -// sel.recv(&r1); -// sel.recv(&r2); -// assert_eq!(sel.ready(), 1); -// assert_eq!(r2.try_recv(), Ok(2)); -// } - -// #[test] -// fn smoke2() { -// let (_s1, r1) = unbounded::<i32>(); -// let (_s2, r2) = unbounded::<i32>(); -// let (_s3, r3) = unbounded::<i32>(); -// let (_s4, r4) = unbounded::<i32>(); -// let (s5, r5) = unbounded::<i32>(); - -// s5.send(5).unwrap(); - -// let mut sel = Select::new(); -// sel.recv(&r1); -// sel.recv(&r2); -// sel.recv(&r3); -// sel.recv(&r4); -// sel.recv(&r5); -// assert_eq!(sel.ready(), 4); -// assert_eq!(r5.try_recv(), Ok(5)); -// } - -// #[test] -// fn disconnected() { -// let (s1, r1) = unbounded::<i32>(); -// let (s2, r2) = unbounded::<i32>(); - -// scope(|scope| { -// scope.spawn(|_| { -// drop(s1); -// thread::sleep(ms(500)); -// s2.send(5).unwrap(); -// }); - -// let mut sel = Select::new(); -// sel.recv(&r1); -// sel.recv(&r2); -// match sel.ready_timeout(ms(1000)) { -// Ok(0) => assert_eq!(r1.try_recv(), Err(TryRecvError::Disconnected)), -// _ => panic!(), -// } - -// r2.recv().unwrap(); -// }) -// .unwrap(); - -// let mut sel = Select::new(); -// sel.recv(&r1); -// sel.recv(&r2); -// match sel.ready_timeout(ms(1000)) { -// Ok(0) => assert_eq!(r1.try_recv(), Err(TryRecvError::Disconnected)), -// _ => panic!(), -// } - -// scope(|scope| { -// scope.spawn(|_| { -// thread::sleep(ms(500)); -// drop(s2); -// }); - -// let mut sel = Select::new(); -// sel.recv(&r2); -// match sel.ready_timeout(ms(1000)) { -// Ok(0) => assert_eq!(r2.try_recv(), Err(TryRecvError::Disconnected)), -// _ => panic!(), -// } -// }) -// .unwrap(); -// } - -// #[test] -// fn default() { -// let (s1, r1) = unbounded::<i32>(); -// let (s2, r2) = unbounded::<i32>(); - -// let mut sel = Select::new(); -// sel.recv(&r1); -// sel.recv(&r2); -// assert!(sel.try_ready().is_err()); - -// drop(s1); - -// let mut sel = Select::new(); -// sel.recv(&r1); -// sel.recv(&r2); -// match sel.try_ready() { -// Ok(0) => assert!(r1.try_recv().is_err()), -// _ => panic!(), -// } - -// s2.send(2).unwrap(); - -// let mut sel = Select::new(); -// sel.recv(&r2); -// match sel.try_ready() { -// Ok(0) => assert_eq!(r2.try_recv(), Ok(2)), -// _ => panic!(), -// } - -// let mut sel = Select::new(); -// sel.recv(&r2); -// assert!(sel.try_ready().is_err()); - -// let mut sel = Select::new(); -// assert!(sel.try_ready().is_err()); -// } - -// #[test] -// fn timeout() { -// let (_s1, r1) = unbounded::<i32>(); -// let (s2, r2) = unbounded::<i32>(); - -// scope(|scope| { -// scope.spawn(|_| { -// thread::sleep(ms(1500)); -// s2.send(2).unwrap(); -// }); - -// let mut sel = Select::new(); -// sel.recv(&r1); -// sel.recv(&r2); -// assert!(sel.ready_timeout(ms(1000)).is_err()); - -// let mut sel = Select::new(); -// sel.recv(&r1); -// sel.recv(&r2); -// match sel.ready_timeout(ms(1000)) { -// Ok(1) => assert_eq!(r2.try_recv(), Ok(2)), -// _ => panic!(), -// } -// }) -// .unwrap(); - -// scope(|scope| { -// let (s, r) = unbounded::<i32>(); - -// scope.spawn(move |_| { -// thread::sleep(ms(500)); -// drop(s); -// }); - -// let mut sel = Select::new(); -// assert!(sel.ready_timeout(ms(1000)).is_err()); - -// let mut sel = Select::new(); -// sel.recv(&r); -// match sel.try_ready() { -// Ok(0) => assert_eq!(r.try_recv(), Err(TryRecvError::Disconnected)), -// _ => panic!(), -// } -// }) -// .unwrap(); -// } - -// #[test] -// fn default_when_disconnected() { -// let (_, r) = unbounded::<i32>(); - -// let mut sel = Select::new(); -// sel.recv(&r); -// match sel.try_ready() { -// Ok(0) => assert_eq!(r.try_recv(), Err(TryRecvError::Disconnected)), -// _ => panic!(), -// } - -// let (_, r) = unbounded::<i32>(); - -// let mut sel = Select::new(); -// sel.recv(&r); -// match sel.ready_timeout(ms(1000)) { -// Ok(0) => assert_eq!(r.try_recv(), Err(TryRecvError::Disconnected)), -// _ => panic!(), -// } - -// let (s, _) = bounded::<i32>(0); - -// let mut sel = Select::new(); -// sel.send(&s); -// match sel.try_ready() { -// Ok(0) => assert_eq!(s.try_send(0), Err(TrySendError::Disconnected(0))), -// _ => panic!(), -// } - -// let (s, _) = bounded::<i32>(0); - -// let mut sel = Select::new(); -// sel.send(&s); -// match sel.ready_timeout(ms(1000)) { -// Ok(0) => assert_eq!(s.try_send(0), Err(TrySendError::Disconnected(0))), -// _ => panic!(), -// } -// } - -// #[test] -// fn default_only() { -// let start = Instant::now(); - -// let mut sel = Select::new(); -// assert!(sel.try_ready().is_err()); -// let now = Instant::now(); -// assert!(now - start <= ms(50)); - -// let start = Instant::now(); -// let mut sel = Select::new(); -// assert!(sel.ready_timeout(ms(500)).is_err()); -// let now = Instant::now(); -// assert!(now - start >= ms(450)); -// assert!(now - start <= ms(550)); -// } - -// #[test] -// fn unblocks() { -// let (s1, r1) = bounded::<i32>(0); -// let (s2, r2) = bounded::<i32>(0); - -// scope(|scope| { -// scope.spawn(|_| { -// thread::sleep(ms(500)); -// s2.send(2).unwrap(); -// }); - -// let mut sel = Select::new(); -// sel.recv(&r1); -// sel.recv(&r2); -// match sel.ready_timeout(ms(1000)) { -// Ok(1) => assert_eq!(r2.try_recv(), Ok(2)), -// _ => panic!(), -// } -// }) -// .unwrap(); - -// scope(|scope| { -// scope.spawn(|_| { -// thread::sleep(ms(500)); -// assert_eq!(r1.recv().unwrap(), 1); -// }); - -// let mut sel = Select::new(); -// let oper1 = sel.send(&s1); -// let oper2 = sel.send(&s2); -// let oper = sel.select_timeout(ms(1000)); -// match oper { -// Err(_) => panic!(), -// Ok(oper) => match oper.index() { -// i if i == oper1 => oper.send(&s1, 1).unwrap(), -// i if i == oper2 => panic!(), -// _ => unreachable!(), -// }, -// } -// }) -// .unwrap(); -// } - -// #[test] -// fn both_ready() { -// let (s1, r1) = bounded(0); -// let (s2, r2) = bounded(0); - -// scope(|scope| { -// scope.spawn(|_| { -// thread::sleep(ms(500)); -// s1.send(1).unwrap(); -// assert_eq!(r2.recv().unwrap(), 2); -// }); - -// for _ in 0..2 { -// let mut sel = Select::new(); -// sel.recv(&r1); -// sel.send(&s2); -// match sel.ready() { -// 0 => assert_eq!(r1.try_recv(), Ok(1)), -// 1 => s2.try_send(2).unwrap(), -// _ => panic!(), -// } -// } -// }) -// .unwrap(); -// } - -// #[test] -// fn cloning1() { -// scope(|scope| { -// let (s1, r1) = unbounded::<i32>(); -// let (_s2, r2) = unbounded::<i32>(); -// let (s3, r3) = unbounded::<()>(); - -// scope.spawn(move |_| { -// r3.recv().unwrap(); -// drop(s1.clone()); -// assert!(r3.try_recv().is_err()); -// s1.send(1).unwrap(); -// r3.recv().unwrap(); -// }); - -// s3.send(()).unwrap(); - -// let mut sel = Select::new(); -// sel.recv(&r1); -// sel.recv(&r2); -// match sel.ready() { -// 0 => drop(r1.try_recv()), -// 1 => drop(r2.try_recv()), -// _ => panic!(), -// } - -// s3.send(()).unwrap(); -// }) -// .unwrap(); -// } - -// #[test] -// fn cloning2() { -// let (s1, r1) = unbounded::<()>(); -// let (s2, r2) = unbounded::<()>(); -// let (_s3, _r3) = unbounded::<()>(); - -// scope(|scope| { -// scope.spawn(move |_| { -// let mut sel = Select::new(); -// sel.recv(&r1); -// sel.recv(&r2); -// match sel.ready() { -// 0 => panic!(), -// 1 => drop(r2.try_recv()), -// _ => panic!(), -// } -// }); - -// thread::sleep(ms(500)); -// drop(s1.clone()); -// s2.send(()).unwrap(); -// }) -// .unwrap(); -// } - -// #[test] -// fn preflight1() { -// let (s, r) = unbounded(); -// s.send(()).unwrap(); - -// let mut sel = Select::new(); -// sel.recv(&r); -// match sel.ready() { -// 0 => drop(r.try_recv()), -// _ => panic!(), -// } -// } - -// #[test] -// fn preflight2() { -// let (s, r) = unbounded(); -// drop(s.clone()); -// s.send(()).unwrap(); -// drop(s); - -// let mut sel = Select::new(); -// sel.recv(&r); -// match sel.ready() { -// 0 => assert_eq!(r.try_recv(), Ok(())), -// _ => panic!(), -// } - -// assert_eq!(r.try_recv(), Err(TryRecvError::Disconnected)); -// } - -// #[test] -// fn preflight3() { -// let (s, r) = unbounded(); -// drop(s.clone()); -// s.send(()).unwrap(); -// drop(s); -// r.recv().unwrap(); - -// let mut sel = Select::new(); -// sel.recv(&r); -// match sel.ready() { -// 0 => assert_eq!(r.try_recv(), Err(TryRecvError::Disconnected)), -// _ => panic!(), -// } -// } - -// #[test] -// fn duplicate_operations() { -// let (s, r) = unbounded::<i32>(); -// let hit = vec![Cell::new(false); 4]; - -// while hit.iter().map(|h| h.get()).any(|hit| !hit) { -// let mut sel = Select::new(); -// sel.recv(&r); -// sel.recv(&r); -// sel.send(&s); -// sel.send(&s); -// match sel.ready() { -// 0 => { -// assert!(r.try_recv().is_ok()); -// hit[0].set(true); -// } -// 1 => { -// assert!(r.try_recv().is_ok()); -// hit[1].set(true); -// } -// 2 => { -// assert!(s.try_send(0).is_ok()); -// hit[2].set(true); -// } -// 3 => { -// assert!(s.try_send(0).is_ok()); -// hit[3].set(true); -// } -// _ => panic!(), -// } -// } -// } - -// #[test] -// fn nesting() { -// let (s, r) = unbounded::<i32>(); - -// let mut sel = Select::new(); -// sel.send(&s); -// match sel.ready() { -// 0 => { -// assert!(s.try_send(0).is_ok()); - -// let mut sel = Select::new(); -// sel.recv(&r); -// match sel.ready() { -// 0 => { -// assert_eq!(r.try_recv(), Ok(0)); - -// let mut sel = Select::new(); -// sel.send(&s); -// match sel.ready() { -// 0 => { -// assert!(s.try_send(1).is_ok()); - -// let mut sel = Select::new(); -// sel.recv(&r); -// match sel.ready() { -// 0 => { -// assert_eq!(r.try_recv(), Ok(1)); -// } -// _ => panic!(), -// } -// } -// _ => panic!(), -// } -// } -// _ => panic!(), -// } -// } -// _ => panic!(), -// } -// } - -// #[test] -// fn stress_recv() { -// const COUNT: usize = 10_000; - -// let (s1, r1) = unbounded(); -// let (s2, r2) = bounded(5); -// let (s3, r3) = bounded(0); - -// scope(|scope| { -// scope.spawn(|_| { -// for i in 0..COUNT { -// s1.send(i).unwrap(); -// r3.recv().unwrap(); - -// s2.send(i).unwrap(); -// r3.recv().unwrap(); -// } -// }); - -// for i in 0..COUNT { -// for _ in 0..2 { -// let mut sel = Select::new(); -// sel.recv(&r1); -// sel.recv(&r2); -// match sel.ready() { -// 0 => assert_eq!(r1.try_recv(), Ok(i)), -// 1 => assert_eq!(r2.try_recv(), Ok(i)), -// _ => panic!(), -// } - -// s3.send(()).unwrap(); -// } -// } -// }) -// .unwrap(); -// } - -// #[test] -// fn stress_send() { -// const COUNT: usize = 10_000; - -// let (s1, r1) = bounded(0); -// let (s2, r2) = bounded(0); -// let (s3, r3) = bounded(100); - -// scope(|scope| { -// scope.spawn(|_| { -// for i in 0..COUNT { -// assert_eq!(r1.recv().unwrap(), i); -// assert_eq!(r2.recv().unwrap(), i); -// r3.recv().unwrap(); -// } -// }); - -// for i in 0..COUNT { -// for _ in 0..2 { -// let mut sel = Select::new(); -// sel.send(&s1); -// sel.send(&s2); -// match sel.ready() { -// 0 => assert!(s1.try_send(i).is_ok()), -// 1 => assert!(s2.try_send(i).is_ok()), -// _ => panic!(), -// } -// } -// s3.send(()).unwrap(); -// } -// }) -// .unwrap(); -// } - -// #[test] -// fn stress_mixed() { -// const COUNT: usize = 10_000; - -// let (s1, r1) = bounded(0); -// let (s2, r2) = bounded(0); -// let (s3, r3) = bounded(100); - -// scope(|scope| { -// scope.spawn(|_| { -// for i in 0..COUNT { -// s1.send(i).unwrap(); -// assert_eq!(r2.recv().unwrap(), i); -// r3.recv().unwrap(); -// } -// }); - -// for i in 0..COUNT { -// for _ in 0..2 { -// let mut sel = Select::new(); -// sel.recv(&r1); -// sel.send(&s2); -// match sel.ready() { -// 0 => assert_eq!(r1.try_recv(), Ok(i)), -// 1 => assert!(s2.try_send(i).is_ok()), -// _ => panic!(), -// } -// } -// s3.send(()).unwrap(); -// } -// }) -// .unwrap(); -// } - -// #[test] -// fn stress_timeout_two_threads() { -// const COUNT: usize = 20; - -// let (s, r) = bounded(2); - -// scope(|scope| { -// scope.spawn(|_| { -// for i in 0..COUNT { -// if i % 2 == 0 { -// thread::sleep(ms(500)); -// } - -// let done = false; -// while !done { -// let mut sel = Select::new(); -// sel.send(&s); -// match sel.ready_timeout(ms(100)) { -// Err(_) => {} -// Ok(0) => { -// assert!(s.try_send(i).is_ok()); -// break; -// } -// Ok(_) => panic!(), -// } -// } -// } -// }); - -// scope.spawn(|_| { -// for i in 0..COUNT { -// if i % 2 == 0 { -// thread::sleep(ms(500)); -// } - -// let mut done = false; -// while !done { -// let mut sel = Select::new(); -// sel.recv(&r); -// match sel.ready_timeout(ms(100)) { -// Err(_) => {} -// Ok(0) => { -// assert_eq!(r.try_recv(), Ok(i)); -// done = true; -// } -// Ok(_) => panic!(), -// } -// } -// } -// }); -// }) -// .unwrap(); -// } - -// #[test] -// fn send_recv_same_channel() { -// let (s, r) = bounded::<i32>(0); -// let mut sel = Select::new(); -// sel.send(&s); -// sel.recv(&r); -// assert!(sel.ready_timeout(ms(100)).is_err()); - -// let (s, r) = unbounded::<i32>(); -// let mut sel = Select::new(); -// sel.send(&s); -// sel.recv(&r); -// match sel.ready_timeout(ms(100)) { -// Err(_) => panic!(), -// Ok(0) => assert!(s.try_send(0).is_ok()), -// Ok(_) => panic!(), -// } -// } - -// #[test] -// fn channel_through_channel() { -// const COUNT: usize = 1000; - -// type T = Box<dyn Any + Send>; - -// for cap in 1..4 { -// let (s, r) = bounded::<T>(cap); - -// scope(|scope| { -// scope.spawn(move |_| { -// let mut s = s; - -// for _ in 0..COUNT { -// let (new_s, new_r) = bounded(cap); -// let new_r: T = Box::new(Some(new_r)); - -// { -// let mut sel = Select::new(); -// sel.send(&s); -// match sel.ready() { -// 0 => assert!(s.try_send(new_r).is_ok()), -// _ => panic!(), -// } -// } - -// s = new_s; -// } -// }); - -// scope.spawn(move |_| { -// let mut r = r; - -// for _ in 0..COUNT { -// let new = { -// let mut sel = Select::new(); -// sel.recv(&r); -// match sel.ready() { -// 0 => r -// .try_recv() -// .unwrap() -// .downcast_mut::<Option<Receiver<T>>>() -// .unwrap() -// .take() -// .unwrap(), -// _ => panic!(), -// } -// }; -// r = new; -// } -// }); -// }) -// .unwrap(); -// } -// } - -// #[test] -// fn fairness1() { -// const COUNT: usize = 10_000; - -// let (s1, r1) = bounded::<()>(COUNT); -// let (s2, r2) = unbounded::<()>(); - -// for _ in 0..COUNT { -// s1.send(()).unwrap(); -// s2.send(()).unwrap(); -// } - -// let hits = vec![Cell::new(0usize); 4]; -// for _ in 0..COUNT { -// let after = after(ms(0)); -// let tick = tick(ms(0)); - -// let mut sel = Select::new(); -// sel.recv(&r1); -// sel.recv(&r2); -// sel.recv(&after); -// sel.recv(&tick); -// match sel.ready() { -// 0 => { -// r1.try_recv().unwrap(); -// hits[0].set(hits[0].get() + 1); -// } -// 1 => { -// r2.try_recv().unwrap(); -// hits[1].set(hits[1].get() + 1); -// } -// 2 => { -// after.try_recv().unwrap(); -// hits[2].set(hits[2].get() + 1); -// } -// 3 => { -// tick.try_recv().unwrap(); -// hits[3].set(hits[3].get() + 1); -// } -// _ => panic!(), -// } -// } -// assert!(hits.iter().all(|x| x.get() >= COUNT / hits.len() / 2)); -// } - -// #[test] -// fn fairness2() { -// const COUNT: usize = 10_000; - -// let (s1, r1) = unbounded::<()>(); -// let (s2, r2) = bounded::<()>(1); -// let (s3, r3) = bounded::<()>(0); - -// scope(|scope| { -// scope.spawn(|_| { -// for _ in 0..COUNT { -// let mut sel = Select::new(); -// let mut oper1 = None; -// let mut oper2 = None; -// if s1.is_empty() { -// oper1 = Some(sel.send(&s1)); -// } -// if s2.is_empty() { -// oper2 = Some(sel.send(&s2)); -// } -// let oper3 = sel.send(&s3); -// let oper = sel.select(); -// match oper.index() { -// i if Some(i) == oper1 => assert!(oper.send(&s1, ()).is_ok()), -// i if Some(i) == oper2 => assert!(oper.send(&s2, ()).is_ok()), -// i if i == oper3 => assert!(oper.send(&s3, ()).is_ok()), -// _ => unreachable!(), -// } -// } -// }); - -// let hits = vec![Cell::new(0usize); 3]; -// for _ in 0..COUNT { -// let mut sel = Select::new(); -// sel.recv(&r1); -// sel.recv(&r2); -// sel.recv(&r3); -// loop { -// match sel.ready() { -// 0 => { -// if r1.try_recv().is_ok() { -// hits[0].set(hits[0].get() + 1); -// break; -// } -// } -// 1 => { -// if r2.try_recv().is_ok() { -// hits[1].set(hits[1].get() + 1); -// break; -// } -// } -// 2 => { -// if r3.try_recv().is_ok() { -// hits[2].set(hits[2].get() + 1); -// break; -// } -// } -// _ => unreachable!(), -// } -// } -// } -// assert!(hits.iter().all(|x| x.get() >= COUNT / hits.len() / 10)); -// }) -// .unwrap(); -// } diff --git a/vendor/flume/tests/same_channel.rs b/vendor/flume/tests/same_channel.rs deleted file mode 100644 index c6452ec..0000000 --- a/vendor/flume/tests/same_channel.rs +++ /dev/null @@ -1,114 +0,0 @@ -// extern crate crossbeam_channel; - -// use std::time::Duration; - -// use crossbeam_channel::{after, bounded, never, tick, unbounded}; - -// fn ms(ms: u64) -> Duration { -// Duration::from_millis(ms) -// } - -// #[test] -// fn after_same_channel() { -// let r = after(ms(50)); - -// let r2 = r.clone(); -// assert!(r.same_channel(&r2)); - -// let r3 = after(ms(50)); -// assert!(!r.same_channel(&r3)); -// assert!(!r2.same_channel(&r3)); - -// let r4 = after(ms(100)); -// assert!(!r.same_channel(&r4)); -// assert!(!r2.same_channel(&r4)); -// } - -// #[test] -// fn array_same_channel() { -// let (s, r) = bounded::<usize>(1); - -// let s2 = s.clone(); -// assert!(s.same_channel(&s2)); - -// let r2 = r.clone(); -// assert!(r.same_channel(&r2)); - -// let (s3, r3) = bounded::<usize>(1); -// assert!(!s.same_channel(&s3)); -// assert!(!s2.same_channel(&s3)); -// assert!(!r.same_channel(&r3)); -// assert!(!r2.same_channel(&r3)); -// } - -// #[test] -// fn list_same_channel() { -// let (s, r) = unbounded::<usize>(); - -// let s2 = s.clone(); -// assert!(s.same_channel(&s2)); - -// let r2 = r.clone(); -// assert!(r.same_channel(&r2)); - -// let (s3, r3) = unbounded::<usize>(); -// assert!(!s.same_channel(&s3)); -// assert!(!s2.same_channel(&s3)); -// assert!(!r.same_channel(&r3)); -// assert!(!r2.same_channel(&r3)); -// } - -// #[test] -// fn never_same_channel() { -// let r = never::<usize>(); - -// let r2 = r.clone(); -// assert!(r.same_channel(&r2)); - -// // Never channel are always equal to one another. -// let r3 = never::<usize>(); -// assert!(r.same_channel(&r3)); -// assert!(r2.same_channel(&r3)); -// } - -// #[test] -// fn tick_same_channel() { -// let r = tick(ms(50)); - -// let r2 = r.clone(); -// assert!(r.same_channel(&r2)); - -// let r3 = tick(ms(50)); -// assert!(!r.same_channel(&r3)); -// assert!(!r2.same_channel(&r3)); - -// let r4 = tick(ms(100)); -// assert!(!r.same_channel(&r4)); -// assert!(!r2.same_channel(&r4)); -// } - -// #[test] -// fn zero_same_channel() { -// let (s, r) = bounded::<usize>(0); - -// let s2 = s.clone(); -// assert!(s.same_channel(&s2)); - -// let r2 = r.clone(); -// assert!(r.same_channel(&r2)); - -// let (s3, r3) = bounded::<usize>(0); -// assert!(!s.same_channel(&s3)); -// assert!(!s2.same_channel(&s3)); -// assert!(!r.same_channel(&r3)); -// assert!(!r2.same_channel(&r3)); -// } - -// #[test] -// fn different_flavors_same_channel() { -// let (s1, r1) = bounded::<usize>(0); -// let (s2, r2) = unbounded::<usize>(); - -// assert!(!s1.same_channel(&s2)); -// assert!(!r1.same_channel(&r2)); -// } diff --git a/vendor/flume/tests/select.rs b/vendor/flume/tests/select.rs deleted file mode 100644 index 4fac9e9..0000000 --- a/vendor/flume/tests/select.rs +++ /dev/null @@ -1,1304 +0,0 @@ -// //! Tests for channel selection using the `Select` struct. - -// extern crate crossbeam_channel; -// extern crate crossbeam_utils; - -// use std::any::Any; -// use std::cell::Cell; -// use std::thread; -// use std::time::{Duration, Instant}; - -// use crossbeam_channel::{after, bounded, tick, unbounded, Receiver, Select, TryRecvError}; -// use crossbeam_utils::thread::scope; - -// fn ms(ms: u64) -> Duration { -// Duration::from_millis(ms) -// } - -// #[test] -// fn smoke1() { -// let (s1, r1) = unbounded::<usize>(); -// let (s2, r2) = unbounded::<usize>(); - -// s1.send(1).unwrap(); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r1); -// let oper2 = sel.recv(&r2); -// let oper = sel.select(); -// match oper.index() { -// i if i == oper1 => assert_eq!(oper.recv(&r1), Ok(1)), -// i if i == oper2 => panic!(), -// _ => unreachable!(), -// } - -// s2.send(2).unwrap(); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r1); -// let oper2 = sel.recv(&r2); -// let oper = sel.select(); -// match oper.index() { -// i if i == oper1 => panic!(), -// i if i == oper2 => assert_eq!(oper.recv(&r2), Ok(2)), -// _ => unreachable!(), -// } -// } - -// #[test] -// fn smoke2() { -// let (_s1, r1) = unbounded::<i32>(); -// let (_s2, r2) = unbounded::<i32>(); -// let (_s3, r3) = unbounded::<i32>(); -// let (_s4, r4) = unbounded::<i32>(); -// let (s5, r5) = unbounded::<i32>(); - -// s5.send(5).unwrap(); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r1); -// let oper2 = sel.recv(&r2); -// let oper3 = sel.recv(&r3); -// let oper4 = sel.recv(&r4); -// let oper5 = sel.recv(&r5); -// let oper = sel.select(); -// match oper.index() { -// i if i == oper1 => panic!(), -// i if i == oper2 => panic!(), -// i if i == oper3 => panic!(), -// i if i == oper4 => panic!(), -// i if i == oper5 => assert_eq!(oper.recv(&r5), Ok(5)), -// _ => unreachable!(), -// } -// } - -// #[test] -// fn disconnected() { -// let (s1, r1) = unbounded::<i32>(); -// let (s2, r2) = unbounded::<i32>(); - -// scope(|scope| { -// scope.spawn(|_| { -// drop(s1); -// thread::sleep(ms(500)); -// s2.send(5).unwrap(); -// }); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r1); -// let oper2 = sel.recv(&r2); -// let oper = sel.select_timeout(ms(1000)); -// match oper { -// Err(_) => panic!(), -// Ok(oper) => match oper.index() { -// i if i == oper1 => assert!(oper.recv(&r1).is_err()), -// i if i == oper2 => panic!(), -// _ => unreachable!(), -// }, -// } - -// r2.recv().unwrap(); -// }) -// .unwrap(); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r1); -// let oper2 = sel.recv(&r2); -// let oper = sel.select_timeout(ms(1000)); -// match oper { -// Err(_) => panic!(), -// Ok(oper) => match oper.index() { -// i if i == oper1 => assert!(oper.recv(&r1).is_err()), -// i if i == oper2 => panic!(), -// _ => unreachable!(), -// }, -// } - -// scope(|scope| { -// scope.spawn(|_| { -// thread::sleep(ms(500)); -// drop(s2); -// }); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r2); -// let oper = sel.select_timeout(ms(1000)); -// match oper { -// Err(_) => panic!(), -// Ok(oper) => match oper.index() { -// i if i == oper1 => assert!(oper.recv(&r2).is_err()), -// _ => unreachable!(), -// }, -// } -// }) -// .unwrap(); -// } - -// #[test] -// fn default() { -// let (s1, r1) = unbounded::<i32>(); -// let (s2, r2) = unbounded::<i32>(); - -// let mut sel = Select::new(); -// let _oper1 = sel.recv(&r1); -// let _oper2 = sel.recv(&r2); -// let oper = sel.try_select(); -// match oper { -// Err(_) => {} -// Ok(_) => panic!(), -// } - -// drop(s1); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r1); -// let oper2 = sel.recv(&r2); -// let oper = sel.try_select(); -// match oper { -// Err(_) => panic!(), -// Ok(oper) => match oper.index() { -// i if i == oper1 => assert!(oper.recv(&r1).is_err()), -// i if i == oper2 => panic!(), -// _ => unreachable!(), -// }, -// } - -// s2.send(2).unwrap(); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r2); -// let oper = sel.try_select(); -// match oper { -// Err(_) => panic!(), -// Ok(oper) => match oper.index() { -// i if i == oper1 => assert_eq!(oper.recv(&r2), Ok(2)), -// _ => unreachable!(), -// }, -// } - -// let mut sel = Select::new(); -// let _oper1 = sel.recv(&r2); -// let oper = sel.try_select(); -// match oper { -// Err(_) => {} -// Ok(_) => panic!(), -// } - -// let mut sel = Select::new(); -// let oper = sel.try_select(); -// match oper { -// Err(_) => {} -// Ok(_) => panic!(), -// } -// } - -// #[test] -// fn timeout() { -// let (_s1, r1) = unbounded::<i32>(); -// let (s2, r2) = unbounded::<i32>(); - -// scope(|scope| { -// scope.spawn(|_| { -// thread::sleep(ms(1500)); -// s2.send(2).unwrap(); -// }); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r1); -// let oper2 = sel.recv(&r2); -// let oper = sel.select_timeout(ms(1000)); -// match oper { -// Err(_) => {} -// Ok(oper) => match oper.index() { -// i if i == oper1 => panic!(), -// i if i == oper2 => panic!(), -// _ => unreachable!(), -// }, -// } - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r1); -// let oper2 = sel.recv(&r2); -// let oper = sel.select_timeout(ms(1000)); -// match oper { -// Err(_) => panic!(), -// Ok(oper) => match oper.index() { -// i if i == oper1 => panic!(), -// i if i == oper2 => assert_eq!(oper.recv(&r2), Ok(2)), -// _ => unreachable!(), -// }, -// } -// }) -// .unwrap(); - -// scope(|scope| { -// let (s, r) = unbounded::<i32>(); - -// scope.spawn(move |_| { -// thread::sleep(ms(500)); -// drop(s); -// }); - -// let mut sel = Select::new(); -// let oper = sel.select_timeout(ms(1000)); -// match oper { -// Err(_) => { -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r); -// let oper = sel.try_select(); -// match oper { -// Err(_) => panic!(), -// Ok(oper) => match oper.index() { -// i if i == oper1 => assert!(oper.recv(&r).is_err()), -// _ => unreachable!(), -// }, -// } -// } -// Ok(_) => unreachable!(), -// } -// }) -// .unwrap(); -// } - -// #[test] -// fn default_when_disconnected() { -// let (_, r) = unbounded::<i32>(); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r); -// let oper = sel.try_select(); -// match oper { -// Err(_) => panic!(), -// Ok(oper) => match oper.index() { -// i if i == oper1 => assert!(oper.recv(&r).is_err()), -// _ => unreachable!(), -// }, -// } - -// let (_, r) = unbounded::<i32>(); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r); -// let oper = sel.select_timeout(ms(1000)); -// match oper { -// Err(_) => panic!(), -// Ok(oper) => match oper.index() { -// i if i == oper1 => assert!(oper.recv(&r).is_err()), -// _ => unreachable!(), -// }, -// } - -// let (s, _) = bounded::<i32>(0); - -// let mut sel = Select::new(); -// let oper1 = sel.send(&s); -// let oper = sel.try_select(); -// match oper { -// Err(_) => panic!(), -// Ok(oper) => match oper.index() { -// i if i == oper1 => assert!(oper.send(&s, 0).is_err()), -// _ => unreachable!(), -// }, -// } - -// let (s, _) = bounded::<i32>(0); - -// let mut sel = Select::new(); -// let oper1 = sel.send(&s); -// let oper = sel.select_timeout(ms(1000)); -// match oper { -// Err(_) => panic!(), -// Ok(oper) => match oper.index() { -// i if i == oper1 => assert!(oper.send(&s, 0).is_err()), -// _ => unreachable!(), -// }, -// } -// } - -// #[test] -// fn default_only() { -// let start = Instant::now(); - -// let mut sel = Select::new(); -// let oper = sel.try_select(); -// assert!(oper.is_err()); -// let now = Instant::now(); -// assert!(now - start <= ms(50)); - -// let start = Instant::now(); -// let mut sel = Select::new(); -// let oper = sel.select_timeout(ms(500)); -// assert!(oper.is_err()); -// let now = Instant::now(); -// assert!(now - start >= ms(450)); -// assert!(now - start <= ms(550)); -// } - -// #[test] -// fn unblocks() { -// let (s1, r1) = bounded::<i32>(0); -// let (s2, r2) = bounded::<i32>(0); - -// scope(|scope| { -// scope.spawn(|_| { -// thread::sleep(ms(500)); -// s2.send(2).unwrap(); -// }); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r1); -// let oper2 = sel.recv(&r2); -// let oper = sel.select_timeout(ms(1000)); -// match oper { -// Err(_) => panic!(), -// Ok(oper) => match oper.index() { -// i if i == oper1 => panic!(), -// i if i == oper2 => assert_eq!(oper.recv(&r2), Ok(2)), -// _ => unreachable!(), -// }, -// } -// }) -// .unwrap(); - -// scope(|scope| { -// scope.spawn(|_| { -// thread::sleep(ms(500)); -// assert_eq!(r1.recv().unwrap(), 1); -// }); - -// let mut sel = Select::new(); -// let oper1 = sel.send(&s1); -// let oper2 = sel.send(&s2); -// let oper = sel.select_timeout(ms(1000)); -// match oper { -// Err(_) => panic!(), -// Ok(oper) => match oper.index() { -// i if i == oper1 => oper.send(&s1, 1).unwrap(), -// i if i == oper2 => panic!(), -// _ => unreachable!(), -// }, -// } -// }) -// .unwrap(); -// } - -// #[test] -// fn both_ready() { -// let (s1, r1) = bounded(0); -// let (s2, r2) = bounded(0); - -// scope(|scope| { -// scope.spawn(|_| { -// thread::sleep(ms(500)); -// s1.send(1).unwrap(); -// assert_eq!(r2.recv().unwrap(), 2); -// }); - -// for _ in 0..2 { -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r1); -// let oper2 = sel.send(&s2); -// let oper = sel.select(); -// match oper.index() { -// i if i == oper1 => assert_eq!(oper.recv(&r1), Ok(1)), -// i if i == oper2 => oper.send(&s2, 2).unwrap(), -// _ => unreachable!(), -// } -// } -// }) -// .unwrap(); -// } - -// #[test] -// fn loop_try() { -// const RUNS: usize = 20; - -// for _ in 0..RUNS { -// let (s1, r1) = bounded::<i32>(0); -// let (s2, r2) = bounded::<i32>(0); -// let (s_end, r_end) = bounded::<()>(0); - -// scope(|scope| { -// scope.spawn(|_| loop { -// let mut done = false; - -// let mut sel = Select::new(); -// let oper1 = sel.send(&s1); -// let oper = sel.try_select(); -// match oper { -// Err(_) => {} -// Ok(oper) => match oper.index() { -// i if i == oper1 => { -// let _ = oper.send(&s1, 1); -// done = true; -// } -// _ => unreachable!(), -// }, -// } -// if done { -// break; -// } - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r_end); -// let oper = sel.try_select(); -// match oper { -// Err(_) => {} -// Ok(oper) => match oper.index() { -// i if i == oper1 => { -// let _ = oper.recv(&r_end); -// done = true; -// } -// _ => unreachable!(), -// }, -// } -// if done { -// break; -// } -// }); - -// scope.spawn(|_| loop { -// if let Ok(x) = r2.try_recv() { -// assert_eq!(x, 2); -// break; -// } - -// let mut done = false; -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r_end); -// let oper = sel.try_select(); -// match oper { -// Err(_) => {} -// Ok(oper) => match oper.index() { -// i if i == oper1 => { -// let _ = oper.recv(&r_end); -// done = true; -// } -// _ => unreachable!(), -// }, -// } -// if done { -// break; -// } -// }); - -// scope.spawn(|_| { -// thread::sleep(ms(500)); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r1); -// let oper2 = sel.send(&s2); -// let oper = sel.select_timeout(ms(1000)); -// match oper { -// Err(_) => {} -// Ok(oper) => match oper.index() { -// i if i == oper1 => assert_eq!(oper.recv(&r1), Ok(1)), -// i if i == oper2 => assert!(oper.send(&s2, 2).is_ok()), -// _ => unreachable!(), -// }, -// } - -// drop(s_end); -// }); -// }) -// .unwrap(); -// } -// } - -// #[test] -// fn cloning1() { -// scope(|scope| { -// let (s1, r1) = unbounded::<i32>(); -// let (_s2, r2) = unbounded::<i32>(); -// let (s3, r3) = unbounded::<()>(); - -// scope.spawn(move |_| { -// r3.recv().unwrap(); -// drop(s1.clone()); -// assert!(r3.try_recv().is_err()); -// s1.send(1).unwrap(); -// r3.recv().unwrap(); -// }); - -// s3.send(()).unwrap(); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r1); -// let oper2 = sel.recv(&r2); -// let oper = sel.select(); -// match oper.index() { -// i if i == oper1 => drop(oper.recv(&r1)), -// i if i == oper2 => drop(oper.recv(&r2)), -// _ => unreachable!(), -// } - -// s3.send(()).unwrap(); -// }) -// .unwrap(); -// } - -// #[test] -// fn cloning2() { -// let (s1, r1) = unbounded::<()>(); -// let (s2, r2) = unbounded::<()>(); -// let (_s3, _r3) = unbounded::<()>(); - -// scope(|scope| { -// scope.spawn(move |_| { -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r1); -// let oper2 = sel.recv(&r2); -// let oper = sel.select(); -// match oper.index() { -// i if i == oper1 => panic!(), -// i if i == oper2 => drop(oper.recv(&r2)), -// _ => unreachable!(), -// } -// }); - -// thread::sleep(ms(500)); -// drop(s1.clone()); -// s2.send(()).unwrap(); -// }) -// .unwrap(); -// } - -// #[test] -// fn preflight1() { -// let (s, r) = unbounded(); -// s.send(()).unwrap(); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r); -// let oper = sel.select(); -// match oper.index() { -// i if i == oper1 => drop(oper.recv(&r)), -// _ => unreachable!(), -// } -// } - -// #[test] -// fn preflight2() { -// let (s, r) = unbounded(); -// drop(s.clone()); -// s.send(()).unwrap(); -// drop(s); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r); -// let oper = sel.select(); -// match oper.index() { -// i if i == oper1 => assert_eq!(oper.recv(&r), Ok(())), -// _ => unreachable!(), -// } - -// assert_eq!(r.try_recv(), Err(TryRecvError::Disconnected)); -// } - -// #[test] -// fn preflight3() { -// let (s, r) = unbounded(); -// drop(s.clone()); -// s.send(()).unwrap(); -// drop(s); -// r.recv().unwrap(); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r); -// let oper = sel.select(); -// match oper.index() { -// i if i == oper1 => assert!(oper.recv(&r).is_err()), -// _ => unreachable!(), -// } -// } - -// #[test] -// fn duplicate_operations() { -// let (s, r) = unbounded::<i32>(); -// let hit = vec![Cell::new(false); 4]; - -// while hit.iter().map(|h| h.get()).any(|hit| !hit) { -// let mut sel = Select::new(); -// let oper0 = sel.recv(&r); -// let oper1 = sel.recv(&r); -// let oper2 = sel.send(&s); -// let oper3 = sel.send(&s); -// let oper = sel.select(); -// match oper.index() { -// i if i == oper0 => { -// assert!(oper.recv(&r).is_ok()); -// hit[0].set(true); -// } -// i if i == oper1 => { -// assert!(oper.recv(&r).is_ok()); -// hit[1].set(true); -// } -// i if i == oper2 => { -// assert!(oper.send(&s, 0).is_ok()); -// hit[2].set(true); -// } -// i if i == oper3 => { -// assert!(oper.send(&s, 0).is_ok()); -// hit[3].set(true); -// } -// _ => unreachable!(), -// } -// } -// } - -// #[test] -// fn nesting() { -// let (s, r) = unbounded::<i32>(); - -// let mut sel = Select::new(); -// let oper1 = sel.send(&s); -// let oper = sel.select(); -// match oper.index() { -// i if i == oper1 => { -// assert!(oper.send(&s, 0).is_ok()); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r); -// let oper = sel.select(); -// match oper.index() { -// i if i == oper1 => { -// assert_eq!(oper.recv(&r), Ok(0)); - -// let mut sel = Select::new(); -// let oper1 = sel.send(&s); -// let oper = sel.select(); -// match oper.index() { -// i if i == oper1 => { -// assert!(oper.send(&s, 1).is_ok()); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r); -// let oper = sel.select(); -// match oper.index() { -// i if i == oper1 => { -// assert_eq!(oper.recv(&r), Ok(1)); -// } -// _ => unreachable!(), -// } -// } -// _ => unreachable!(), -// } -// } -// _ => unreachable!(), -// } -// } -// _ => unreachable!(), -// } -// } - -// #[test] -// fn stress_recv() { -// const COUNT: usize = 10_000; - -// let (s1, r1) = unbounded(); -// let (s2, r2) = bounded(5); -// let (s3, r3) = bounded(100); - -// scope(|scope| { -// scope.spawn(|_| { -// for i in 0..COUNT { -// s1.send(i).unwrap(); -// r3.recv().unwrap(); - -// s2.send(i).unwrap(); -// r3.recv().unwrap(); -// } -// }); - -// for i in 0..COUNT { -// for _ in 0..2 { -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r1); -// let oper2 = sel.recv(&r2); -// let oper = sel.select(); -// match oper.index() { -// ix if ix == oper1 => assert_eq!(oper.recv(&r1), Ok(i)), -// ix if ix == oper2 => assert_eq!(oper.recv(&r2), Ok(i)), -// _ => unreachable!(), -// } - -// s3.send(()).unwrap(); -// } -// } -// }) -// .unwrap(); -// } - -// #[test] -// fn stress_send() { -// const COUNT: usize = 10_000; - -// let (s1, r1) = bounded(0); -// let (s2, r2) = bounded(0); -// let (s3, r3) = bounded(100); - -// scope(|scope| { -// scope.spawn(|_| { -// for i in 0..COUNT { -// assert_eq!(r1.recv().unwrap(), i); -// assert_eq!(r2.recv().unwrap(), i); -// r3.recv().unwrap(); -// } -// }); - -// for i in 0..COUNT { -// for _ in 0..2 { -// let mut sel = Select::new(); -// let oper1 = sel.send(&s1); -// let oper2 = sel.send(&s2); -// let oper = sel.select(); -// match oper.index() { -// ix if ix == oper1 => assert!(oper.send(&s1, i).is_ok()), -// ix if ix == oper2 => assert!(oper.send(&s2, i).is_ok()), -// _ => unreachable!(), -// } -// } -// s3.send(()).unwrap(); -// } -// }) -// .unwrap(); -// } - -// #[test] -// fn stress_mixed() { -// const COUNT: usize = 10_000; - -// let (s1, r1) = bounded(0); -// let (s2, r2) = bounded(0); -// let (s3, r3) = bounded(100); - -// scope(|scope| { -// scope.spawn(|_| { -// for i in 0..COUNT { -// s1.send(i).unwrap(); -// assert_eq!(r2.recv().unwrap(), i); -// r3.recv().unwrap(); -// } -// }); - -// for i in 0..COUNT { -// for _ in 0..2 { -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r1); -// let oper2 = sel.send(&s2); -// let oper = sel.select(); -// match oper.index() { -// ix if ix == oper1 => assert_eq!(oper.recv(&r1), Ok(i)), -// ix if ix == oper2 => assert!(oper.send(&s2, i).is_ok()), -// _ => unreachable!(), -// } -// } -// s3.send(()).unwrap(); -// } -// }) -// .unwrap(); -// } - -// #[test] -// fn stress_timeout_two_threads() { -// const COUNT: usize = 20; - -// let (s, r) = bounded(2); - -// scope(|scope| { -// scope.spawn(|_| { -// for i in 0..COUNT { -// if i % 2 == 0 { -// thread::sleep(ms(500)); -// } - -// let done = false; -// while !done { -// let mut sel = Select::new(); -// let oper1 = sel.send(&s); -// let oper = sel.select_timeout(ms(100)); -// match oper { -// Err(_) => {} -// Ok(oper) => match oper.index() { -// ix if ix == oper1 => { -// assert!(oper.send(&s, i).is_ok()); -// break; -// } -// _ => unreachable!(), -// }, -// } -// } -// } -// }); - -// scope.spawn(|_| { -// for i in 0..COUNT { -// if i % 2 == 0 { -// thread::sleep(ms(500)); -// } - -// let mut done = false; -// while !done { -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r); -// let oper = sel.select_timeout(ms(100)); -// match oper { -// Err(_) => {} -// Ok(oper) => match oper.index() { -// ix if ix == oper1 => { -// assert_eq!(oper.recv(&r), Ok(i)); -// done = true; -// } -// _ => unreachable!(), -// }, -// } -// } -// } -// }); -// }) -// .unwrap(); -// } - -// #[test] -// fn send_recv_same_channel() { -// let (s, r) = bounded::<i32>(0); -// let mut sel = Select::new(); -// let oper1 = sel.send(&s); -// let oper2 = sel.recv(&r); -// let oper = sel.select_timeout(ms(100)); -// match oper { -// Err(_) => {} -// Ok(oper) => match oper.index() { -// ix if ix == oper1 => panic!(), -// ix if ix == oper2 => panic!(), -// _ => unreachable!(), -// }, -// } - -// let (s, r) = unbounded::<i32>(); -// let mut sel = Select::new(); -// let oper1 = sel.send(&s); -// let oper2 = sel.recv(&r); -// let oper = sel.select_timeout(ms(100)); -// match oper { -// Err(_) => panic!(), -// Ok(oper) => match oper.index() { -// ix if ix == oper1 => assert!(oper.send(&s, 0).is_ok()), -// ix if ix == oper2 => panic!(), -// _ => unreachable!(), -// }, -// } -// } - -// #[test] -// fn matching() { -// const THREADS: usize = 44; - -// let (s, r) = &bounded::<usize>(0); - -// scope(|scope| { -// for i in 0..THREADS { -// scope.spawn(move |_| { -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r); -// let oper2 = sel.send(&s); -// let oper = sel.select(); -// match oper.index() { -// ix if ix == oper1 => assert_ne!(oper.recv(&r), Ok(i)), -// ix if ix == oper2 => assert!(oper.send(&s, i).is_ok()), -// _ => unreachable!(), -// } -// }); -// } -// }) -// .unwrap(); - -// assert_eq!(r.try_recv(), Err(TryRecvError::Empty)); -// } - -// #[test] -// fn matching_with_leftover() { -// const THREADS: usize = 55; - -// let (s, r) = &bounded::<usize>(0); - -// scope(|scope| { -// for i in 0..THREADS { -// scope.spawn(move |_| { -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r); -// let oper2 = sel.send(&s); -// let oper = sel.select(); -// match oper.index() { -// ix if ix == oper1 => assert_ne!(oper.recv(&r), Ok(i)), -// ix if ix == oper2 => assert!(oper.send(&s, i).is_ok()), -// _ => unreachable!(), -// } -// }); -// } -// s.send(!0).unwrap(); -// }) -// .unwrap(); - -// assert_eq!(r.try_recv(), Err(TryRecvError::Empty)); -// } - -// #[test] -// fn channel_through_channel() { -// const COUNT: usize = 1000; - -// type T = Box<dyn Any + Send>; - -// for cap in 0..3 { -// let (s, r) = bounded::<T>(cap); - -// scope(|scope| { -// scope.spawn(move |_| { -// let mut s = s; - -// for _ in 0..COUNT { -// let (new_s, new_r) = bounded(cap); -// let new_r: T = Box::new(Some(new_r)); - -// { -// let mut sel = Select::new(); -// let oper1 = sel.send(&s); -// let oper = sel.select(); -// match oper.index() { -// ix if ix == oper1 => assert!(oper.send(&s, new_r).is_ok()), -// _ => unreachable!(), -// } -// } - -// s = new_s; -// } -// }); - -// scope.spawn(move |_| { -// let mut r = r; - -// for _ in 0..COUNT { -// let new = { -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r); -// let oper = sel.select(); -// match oper.index() { -// ix if ix == oper1 => oper -// .recv(&r) -// .unwrap() -// .downcast_mut::<Option<Receiver<T>>>() -// .unwrap() -// .take() -// .unwrap(), -// _ => unreachable!(), -// } -// }; -// r = new; -// } -// }); -// }) -// .unwrap(); -// } -// } - -// #[test] -// fn linearizable_try() { -// const COUNT: usize = 100_000; - -// for step in 0..2 { -// let (start_s, start_r) = bounded::<()>(0); -// let (end_s, end_r) = bounded::<()>(0); - -// let ((s1, r1), (s2, r2)) = if step == 0 { -// (bounded::<i32>(1), bounded::<i32>(1)) -// } else { -// (unbounded::<i32>(), unbounded::<i32>()) -// }; - -// scope(|scope| { -// scope.spawn(|_| { -// for _ in 0..COUNT { -// start_s.send(()).unwrap(); - -// s1.send(1).unwrap(); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r1); -// let oper2 = sel.recv(&r2); -// let oper = sel.try_select(); -// match oper { -// Err(_) => unreachable!(), -// Ok(oper) => match oper.index() { -// ix if ix == oper1 => assert!(oper.recv(&r1).is_ok()), -// ix if ix == oper2 => assert!(oper.recv(&r2).is_ok()), -// _ => unreachable!(), -// }, -// } - -// end_s.send(()).unwrap(); -// let _ = r2.try_recv(); -// } -// }); - -// for _ in 0..COUNT { -// start_r.recv().unwrap(); - -// s2.send(1).unwrap(); -// let _ = r1.try_recv(); - -// end_r.recv().unwrap(); -// } -// }) -// .unwrap(); -// } -// } - -// #[test] -// fn linearizable_timeout() { -// const COUNT: usize = 100_000; - -// for step in 0..2 { -// let (start_s, start_r) = bounded::<()>(0); -// let (end_s, end_r) = bounded::<()>(0); - -// let ((s1, r1), (s2, r2)) = if step == 0 { -// (bounded::<i32>(1), bounded::<i32>(1)) -// } else { -// (unbounded::<i32>(), unbounded::<i32>()) -// }; - -// scope(|scope| { -// scope.spawn(|_| { -// for _ in 0..COUNT { -// start_s.send(()).unwrap(); - -// s1.send(1).unwrap(); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r1); -// let oper2 = sel.recv(&r2); -// let oper = sel.select_timeout(ms(0)); -// match oper { -// Err(_) => unreachable!(), -// Ok(oper) => match oper.index() { -// ix if ix == oper1 => assert!(oper.recv(&r1).is_ok()), -// ix if ix == oper2 => assert!(oper.recv(&r2).is_ok()), -// _ => unreachable!(), -// }, -// } - -// end_s.send(()).unwrap(); -// let _ = r2.try_recv(); -// } -// }); - -// for _ in 0..COUNT { -// start_r.recv().unwrap(); - -// s2.send(1).unwrap(); -// let _ = r1.try_recv(); - -// end_r.recv().unwrap(); -// } -// }) -// .unwrap(); -// } -// } - -// #[test] -// fn fairness1() { -// const COUNT: usize = 10_000; - -// let (s1, r1) = bounded::<()>(COUNT); -// let (s2, r2) = unbounded::<()>(); - -// for _ in 0..COUNT { -// s1.send(()).unwrap(); -// s2.send(()).unwrap(); -// } - -// let hits = vec![Cell::new(0usize); 4]; -// for _ in 0..COUNT { -// let after = after(ms(0)); -// let tick = tick(ms(0)); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r1); -// let oper2 = sel.recv(&r2); -// let oper3 = sel.recv(&after); -// let oper4 = sel.recv(&tick); -// let oper = sel.select(); -// match oper.index() { -// i if i == oper1 => { -// oper.recv(&r1).unwrap(); -// hits[0].set(hits[0].get() + 1); -// } -// i if i == oper2 => { -// oper.recv(&r2).unwrap(); -// hits[1].set(hits[1].get() + 1); -// } -// i if i == oper3 => { -// oper.recv(&after).unwrap(); -// hits[2].set(hits[2].get() + 1); -// } -// i if i == oper4 => { -// oper.recv(&tick).unwrap(); -// hits[3].set(hits[3].get() + 1); -// } -// _ => unreachable!(), -// } -// } -// assert!(hits.iter().all(|x| x.get() >= COUNT / hits.len() / 2)); -// } - -// #[test] -// fn fairness2() { -// const COUNT: usize = 10_000; - -// let (s1, r1) = unbounded::<()>(); -// let (s2, r2) = bounded::<()>(1); -// let (s3, r3) = bounded::<()>(0); - -// scope(|scope| { -// scope.spawn(|_| { -// for _ in 0..COUNT { -// let mut sel = Select::new(); -// let mut oper1 = None; -// let mut oper2 = None; -// if s1.is_empty() { -// oper1 = Some(sel.send(&s1)); -// } -// if s2.is_empty() { -// oper2 = Some(sel.send(&s2)); -// } -// let oper3 = sel.send(&s3); -// let oper = sel.select(); -// match oper.index() { -// i if Some(i) == oper1 => assert!(oper.send(&s1, ()).is_ok()), -// i if Some(i) == oper2 => assert!(oper.send(&s2, ()).is_ok()), -// i if i == oper3 => assert!(oper.send(&s3, ()).is_ok()), -// _ => unreachable!(), -// } -// } -// }); - -// let hits = vec![Cell::new(0usize); 3]; -// for _ in 0..COUNT { -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r1); -// let oper2 = sel.recv(&r2); -// let oper3 = sel.recv(&r3); -// let oper = sel.select(); -// match oper.index() { -// i if i == oper1 => { -// oper.recv(&r1).unwrap(); -// hits[0].set(hits[0].get() + 1); -// } -// i if i == oper2 => { -// oper.recv(&r2).unwrap(); -// hits[1].set(hits[1].get() + 1); -// } -// i if i == oper3 => { -// oper.recv(&r3).unwrap(); -// hits[2].set(hits[2].get() + 1); -// } -// _ => unreachable!(), -// } -// } -// assert!(hits.iter().all(|x| x.get() >= COUNT / hits.len() / 50)); -// }) -// .unwrap(); -// } - -// #[test] -// fn sync_and_clone() { -// const THREADS: usize = 20; - -// let (s, r) = &bounded::<usize>(0); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r); -// let oper2 = sel.send(&s); -// let sel = &sel; - -// scope(|scope| { -// for i in 0..THREADS { -// scope.spawn(move |_| { -// let mut sel = sel.clone(); -// let oper = sel.select(); -// match oper.index() { -// ix if ix == oper1 => assert_ne!(oper.recv(&r), Ok(i)), -// ix if ix == oper2 => assert!(oper.send(&s, i).is_ok()), -// _ => unreachable!(), -// } -// }); -// } -// }) -// .unwrap(); - -// assert_eq!(r.try_recv(), Err(TryRecvError::Empty)); -// } - -// #[test] -// fn send_and_clone() { -// const THREADS: usize = 20; - -// let (s, r) = &bounded::<usize>(0); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r); -// let oper2 = sel.send(&s); - -// scope(|scope| { -// for i in 0..THREADS { -// let mut sel = sel.clone(); -// scope.spawn(move |_| { -// let oper = sel.select(); -// match oper.index() { -// ix if ix == oper1 => assert_ne!(oper.recv(&r), Ok(i)), -// ix if ix == oper2 => assert!(oper.send(&s, i).is_ok()), -// _ => unreachable!(), -// } -// }); -// } -// }) -// .unwrap(); - -// assert_eq!(r.try_recv(), Err(TryRecvError::Empty)); -// } - -// #[test] -// fn reuse() { -// const COUNT: usize = 10_000; - -// let (s1, r1) = bounded(0); -// let (s2, r2) = bounded(0); -// let (s3, r3) = bounded(100); - -// scope(|scope| { -// scope.spawn(|_| { -// for i in 0..COUNT { -// s1.send(i).unwrap(); -// assert_eq!(r2.recv().unwrap(), i); -// r3.recv().unwrap(); -// } -// }); - -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r1); -// let oper2 = sel.send(&s2); - -// for i in 0..COUNT { -// for _ in 0..2 { -// let oper = sel.select(); -// match oper.index() { -// ix if ix == oper1 => assert_eq!(oper.recv(&r1), Ok(i)), -// ix if ix == oper2 => assert!(oper.send(&s2, i).is_ok()), -// _ => unreachable!(), -// } -// } -// s3.send(()).unwrap(); -// } -// }) -// .unwrap(); -// } diff --git a/vendor/flume/tests/select_macro.rs b/vendor/flume/tests/select_macro.rs deleted file mode 100644 index 367d8dd..0000000 --- a/vendor/flume/tests/select_macro.rs +++ /dev/null @@ -1,1440 +0,0 @@ -// //! Tests for the `select!` macro. - -// #![deny(unsafe_code)] - -// #[macro_use] -// extern crate crossbeam_channel; -// extern crate crossbeam_utils; - -// use std::any::Any; -// use std::cell::Cell; -// use std::ops::Deref; -// use std::thread; -// use std::time::{Duration, Instant}; - -// use crossbeam_channel::{after, bounded, never, tick, unbounded}; -// use crossbeam_channel::{Receiver, RecvError, SendError, Sender, TryRecvError}; -// use crossbeam_utils::thread::scope; - -// fn ms(ms: u64) -> Duration { -// Duration::from_millis(ms) -// } - -// #[test] -// fn smoke1() { -// let (s1, r1) = unbounded::<usize>(); -// let (s2, r2) = unbounded::<usize>(); - -// s1.send(1).unwrap(); - -// select! { -// recv(r1) -> v => assert_eq!(v, Ok(1)), -// recv(r2) -> _ => panic!(), -// } - -// s2.send(2).unwrap(); - -// select! { -// recv(r1) -> _ => panic!(), -// recv(r2) -> v => assert_eq!(v, Ok(2)), -// } -// } - -// #[test] -// fn smoke2() { -// let (_s1, r1) = unbounded::<i32>(); -// let (_s2, r2) = unbounded::<i32>(); -// let (_s3, r3) = unbounded::<i32>(); -// let (_s4, r4) = unbounded::<i32>(); -// let (s5, r5) = unbounded::<i32>(); - -// s5.send(5).unwrap(); - -// select! { -// recv(r1) -> _ => panic!(), -// recv(r2) -> _ => panic!(), -// recv(r3) -> _ => panic!(), -// recv(r4) -> _ => panic!(), -// recv(r5) -> v => assert_eq!(v, Ok(5)), -// } -// } - -// #[test] -// fn disconnected() { -// let (s1, r1) = unbounded::<i32>(); -// let (s2, r2) = unbounded::<i32>(); - -// scope(|scope| { -// scope.spawn(|_| { -// drop(s1); -// thread::sleep(ms(500)); -// s2.send(5).unwrap(); -// }); - -// select! { -// recv(r1) -> v => assert!(v.is_err()), -// recv(r2) -> _ => panic!(), -// default(ms(1000)) => panic!(), -// } - -// r2.recv().unwrap(); -// }) -// .unwrap(); - -// select! { -// recv(r1) -> v => assert!(v.is_err()), -// recv(r2) -> _ => panic!(), -// default(ms(1000)) => panic!(), -// } - -// scope(|scope| { -// scope.spawn(|_| { -// thread::sleep(ms(500)); -// drop(s2); -// }); - -// select! { -// recv(r2) -> v => assert!(v.is_err()), -// default(ms(1000)) => panic!(), -// } -// }) -// .unwrap(); -// } - -// #[test] -// fn default() { -// let (s1, r1) = unbounded::<i32>(); -// let (s2, r2) = unbounded::<i32>(); - -// select! { -// recv(r1) -> _ => panic!(), -// recv(r2) -> _ => panic!(), -// default => {} -// } - -// drop(s1); - -// select! { -// recv(r1) -> v => assert!(v.is_err()), -// recv(r2) -> _ => panic!(), -// default => panic!(), -// } - -// s2.send(2).unwrap(); - -// select! { -// recv(r2) -> v => assert_eq!(v, Ok(2)), -// default => panic!(), -// } - -// select! { -// recv(r2) -> _ => panic!(), -// default => {}, -// } - -// select! { -// default => {}, -// } -// } - -// #[test] -// fn timeout() { -// let (_s1, r1) = unbounded::<i32>(); -// let (s2, r2) = unbounded::<i32>(); - -// scope(|scope| { -// scope.spawn(|_| { -// thread::sleep(ms(1500)); -// s2.send(2).unwrap(); -// }); - -// select! { -// recv(r1) -> _ => panic!(), -// recv(r2) -> _ => panic!(), -// default(ms(1000)) => {}, -// } - -// select! { -// recv(r1) -> _ => panic!(), -// recv(r2) -> v => assert_eq!(v, Ok(2)), -// default(ms(1000)) => panic!(), -// } -// }) -// .unwrap(); - -// scope(|scope| { -// let (s, r) = unbounded::<i32>(); - -// scope.spawn(move |_| { -// thread::sleep(ms(500)); -// drop(s); -// }); - -// select! { -// default(ms(1000)) => { -// select! { -// recv(r) -> v => assert!(v.is_err()), -// default => panic!(), -// } -// } -// } -// }) -// .unwrap(); -// } - -// #[test] -// fn default_when_disconnected() { -// let (_, r) = unbounded::<i32>(); - -// select! { -// recv(r) -> res => assert!(res.is_err()), -// default => panic!(), -// } - -// let (_, r) = unbounded::<i32>(); - -// select! { -// recv(r) -> res => assert!(res.is_err()), -// default(ms(1000)) => panic!(), -// } - -// let (s, _) = bounded::<i32>(0); - -// select! { -// send(s, 0) -> res => assert!(res.is_err()), -// default => panic!(), -// } - -// let (s, _) = bounded::<i32>(0); - -// select! { -// send(s, 0) -> res => assert!(res.is_err()), -// default(ms(1000)) => panic!(), -// } -// } - -// #[test] -// fn default_only() { -// let start = Instant::now(); -// select! { -// default => {} -// } -// let now = Instant::now(); -// assert!(now - start <= ms(50)); - -// let start = Instant::now(); -// select! { -// default(ms(500)) => {} -// } -// let now = Instant::now(); -// assert!(now - start >= ms(450)); -// assert!(now - start <= ms(550)); -// } - -// #[test] -// fn unblocks() { -// let (s1, r1) = bounded::<i32>(0); -// let (s2, r2) = bounded::<i32>(0); - -// scope(|scope| { -// scope.spawn(|_| { -// thread::sleep(ms(500)); -// s2.send(2).unwrap(); -// }); - -// select! { -// recv(r1) -> _ => panic!(), -// recv(r2) -> v => assert_eq!(v, Ok(2)), -// default(ms(1000)) => panic!(), -// } -// }) -// .unwrap(); - -// scope(|scope| { -// scope.spawn(|_| { -// thread::sleep(ms(500)); -// assert_eq!(r1.recv().unwrap(), 1); -// }); - -// select! { -// send(s1, 1) -> _ => {}, -// send(s2, 2) -> _ => panic!(), -// default(ms(1000)) => panic!(), -// } -// }) -// .unwrap(); -// } - -// #[test] -// fn both_ready() { -// let (s1, r1) = bounded(0); -// let (s2, r2) = bounded(0); - -// scope(|scope| { -// scope.spawn(|_| { -// thread::sleep(ms(500)); -// s1.send(1).unwrap(); -// assert_eq!(r2.recv().unwrap(), 2); -// }); - -// for _ in 0..2 { -// select! { -// recv(r1) -> v => assert_eq!(v, Ok(1)), -// send(s2, 2) -> _ => {}, -// } -// } -// }) -// .unwrap(); -// } - -// #[test] -// fn loop_try() { -// const RUNS: usize = 20; - -// for _ in 0..RUNS { -// let (s1, r1) = bounded::<i32>(0); -// let (s2, r2) = bounded::<i32>(0); -// let (s_end, r_end) = bounded::<()>(0); - -// scope(|scope| { -// scope.spawn(|_| loop { -// select! { -// send(s1, 1) -> _ => break, -// default => {} -// } - -// select! { -// recv(r_end) -> _ => break, -// default => {} -// } -// }); - -// scope.spawn(|_| loop { -// if let Ok(x) = r2.try_recv() { -// assert_eq!(x, 2); -// break; -// } - -// select! { -// recv(r_end) -> _ => break, -// default => {} -// } -// }); - -// scope.spawn(|_| { -// thread::sleep(ms(500)); - -// select! { -// recv(r1) -> v => assert_eq!(v, Ok(1)), -// send(s2, 2) -> _ => {}, -// default(ms(500)) => panic!(), -// } - -// drop(s_end); -// }); -// }) -// .unwrap(); -// } -// } - -// #[test] -// fn cloning1() { -// scope(|scope| { -// let (s1, r1) = unbounded::<i32>(); -// let (_s2, r2) = unbounded::<i32>(); -// let (s3, r3) = unbounded::<()>(); - -// scope.spawn(move |_| { -// r3.recv().unwrap(); -// drop(s1.clone()); -// assert_eq!(r3.try_recv(), Err(TryRecvError::Empty)); -// s1.send(1).unwrap(); -// r3.recv().unwrap(); -// }); - -// s3.send(()).unwrap(); - -// select! { -// recv(r1) -> _ => {}, -// recv(r2) -> _ => {}, -// } - -// s3.send(()).unwrap(); -// }) -// .unwrap(); -// } - -// #[test] -// fn cloning2() { -// let (s1, r1) = unbounded::<()>(); -// let (s2, r2) = unbounded::<()>(); -// let (_s3, _r3) = unbounded::<()>(); - -// scope(|scope| { -// scope.spawn(move |_| { -// select! { -// recv(r1) -> _ => panic!(), -// recv(r2) -> _ => {}, -// } -// }); - -// thread::sleep(ms(500)); -// drop(s1.clone()); -// s2.send(()).unwrap(); -// }) -// .unwrap(); -// } - -// #[test] -// fn preflight1() { -// let (s, r) = unbounded(); -// s.send(()).unwrap(); - -// select! { -// recv(r) -> _ => {} -// } -// } - -// #[test] -// fn preflight2() { -// let (s, r) = unbounded(); -// drop(s.clone()); -// s.send(()).unwrap(); -// drop(s); - -// select! { -// recv(r) -> v => assert!(v.is_ok()), -// } -// assert_eq!(r.try_recv(), Err(TryRecvError::Disconnected)); -// } - -// #[test] -// fn preflight3() { -// let (s, r) = unbounded(); -// drop(s.clone()); -// s.send(()).unwrap(); -// drop(s); -// r.recv().unwrap(); - -// select! { -// recv(r) -> v => assert!(v.is_err()) -// } -// } - -// #[test] -// fn duplicate_operations() { -// let (s, r) = unbounded::<i32>(); -// let mut hit = [false; 4]; - -// while hit.iter().any(|hit| !hit) { -// select! { -// recv(r) -> _ => hit[0] = true, -// recv(r) -> _ => hit[1] = true, -// send(s, 0) -> _ => hit[2] = true, -// send(s, 0) -> _ => hit[3] = true, -// } -// } -// } - -// #[test] -// fn nesting() { -// let (s, r) = unbounded::<i32>(); - -// select! { -// send(s, 0) -> _ => { -// select! { -// recv(r) -> v => { -// assert_eq!(v, Ok(0)); -// select! { -// send(s, 1) -> _ => { -// select! { -// recv(r) -> v => { -// assert_eq!(v, Ok(1)); -// } -// } -// } -// } -// } -// } -// } -// } -// } - -// #[test] -// #[should_panic(expected = "send panicked")] -// fn panic_sender() { -// fn get() -> Sender<i32> { -// panic!("send panicked") -// } - -// #[allow(unreachable_code)] -// { -// select! { -// send(get(), panic!()) -> _ => {} -// } -// } -// } - -// #[test] -// #[should_panic(expected = "recv panicked")] -// fn panic_receiver() { -// fn get() -> Receiver<i32> { -// panic!("recv panicked") -// } - -// select! { -// recv(get()) -> _ => {} -// } -// } - -// #[test] -// fn stress_recv() { -// const COUNT: usize = 10_000; - -// let (s1, r1) = unbounded(); -// let (s2, r2) = bounded(5); -// let (s3, r3) = bounded(100); - -// scope(|scope| { -// scope.spawn(|_| { -// for i in 0..COUNT { -// s1.send(i).unwrap(); -// r3.recv().unwrap(); - -// s2.send(i).unwrap(); -// r3.recv().unwrap(); -// } -// }); - -// for i in 0..COUNT { -// for _ in 0..2 { -// select! { -// recv(r1) -> v => assert_eq!(v, Ok(i)), -// recv(r2) -> v => assert_eq!(v, Ok(i)), -// } - -// s3.send(()).unwrap(); -// } -// } -// }) -// .unwrap(); -// } - -// #[test] -// fn stress_send() { -// const COUNT: usize = 10_000; - -// let (s1, r1) = bounded(0); -// let (s2, r2) = bounded(0); -// let (s3, r3) = bounded(100); - -// scope(|scope| { -// scope.spawn(|_| { -// for i in 0..COUNT { -// assert_eq!(r1.recv().unwrap(), i); -// assert_eq!(r2.recv().unwrap(), i); -// r3.recv().unwrap(); -// } -// }); - -// for i in 0..COUNT { -// for _ in 0..2 { -// select! { -// send(s1, i) -> _ => {}, -// send(s2, i) -> _ => {}, -// } -// } -// s3.send(()).unwrap(); -// } -// }) -// .unwrap(); -// } - -// #[test] -// fn stress_mixed() { -// const COUNT: usize = 10_000; - -// let (s1, r1) = bounded(0); -// let (s2, r2) = bounded(0); -// let (s3, r3) = bounded(100); - -// scope(|scope| { -// scope.spawn(|_| { -// for i in 0..COUNT { -// s1.send(i).unwrap(); -// assert_eq!(r2.recv().unwrap(), i); -// r3.recv().unwrap(); -// } -// }); - -// for i in 0..COUNT { -// for _ in 0..2 { -// select! { -// recv(r1) -> v => assert_eq!(v, Ok(i)), -// send(s2, i) -> _ => {}, -// } -// } -// s3.send(()).unwrap(); -// } -// }) -// .unwrap(); -// } - -// #[test] -// fn stress_timeout_two_threads() { -// const COUNT: usize = 20; - -// let (s, r) = bounded(2); - -// scope(|scope| { -// scope.spawn(|_| { -// for i in 0..COUNT { -// if i % 2 == 0 { -// thread::sleep(ms(500)); -// } - -// loop { -// select! { -// send(s, i) -> _ => break, -// default(ms(100)) => {} -// } -// } -// } -// }); - -// scope.spawn(|_| { -// for i in 0..COUNT { -// if i % 2 == 0 { -// thread::sleep(ms(500)); -// } - -// loop { -// select! { -// recv(r) -> v => { -// assert_eq!(v, Ok(i)); -// break; -// } -// default(ms(100)) => {} -// } -// } -// } -// }); -// }) -// .unwrap(); -// } - -// #[test] -// fn send_recv_same_channel() { -// let (s, r) = bounded::<i32>(0); -// select! { -// send(s, 0) -> _ => panic!(), -// recv(r) -> _ => panic!(), -// default(ms(500)) => {} -// } - -// let (s, r) = unbounded::<i32>(); -// select! { -// send(s, 0) -> _ => {}, -// recv(r) -> _ => panic!(), -// default(ms(500)) => panic!(), -// } -// } - -// #[test] -// fn matching() { -// const THREADS: usize = 44; - -// let (s, r) = &bounded::<usize>(0); - -// scope(|scope| { -// for i in 0..THREADS { -// scope.spawn(move |_| { -// select! { -// recv(r) -> v => assert_ne!(v.unwrap(), i), -// send(s, i) -> _ => {}, -// } -// }); -// } -// }) -// .unwrap(); - -// assert_eq!(r.try_recv(), Err(TryRecvError::Empty)); -// } - -// #[test] -// fn matching_with_leftover() { -// const THREADS: usize = 55; - -// let (s, r) = &bounded::<usize>(0); - -// scope(|scope| { -// for i in 0..THREADS { -// scope.spawn(move |_| { -// select! { -// recv(r) -> v => assert_ne!(v.unwrap(), i), -// send(s, i) -> _ => {}, -// } -// }); -// } -// s.send(!0).unwrap(); -// }) -// .unwrap(); - -// assert_eq!(r.try_recv(), Err(TryRecvError::Empty)); -// } - -// #[test] -// fn channel_through_channel() { -// const COUNT: usize = 1000; - -// type T = Box<dyn Any + Send>; - -// for cap in 0..3 { -// let (s, r) = bounded::<T>(cap); - -// scope(|scope| { -// scope.spawn(move |_| { -// let mut s = s; - -// for _ in 0..COUNT { -// let (new_s, new_r) = bounded(cap); -// let new_r: T = Box::new(Some(new_r)); - -// select! { -// send(s, new_r) -> _ => {} -// } - -// s = new_s; -// } -// }); - -// scope.spawn(move |_| { -// let mut r = r; - -// for _ in 0..COUNT { -// r = select! { -// recv(r) -> msg => { -// msg.unwrap() -// .downcast_mut::<Option<Receiver<T>>>() -// .unwrap() -// .take() -// .unwrap() -// } -// } -// } -// }); -// }) -// .unwrap(); -// } -// } - -// #[test] -// fn linearizable_default() { -// const COUNT: usize = 100_000; - -// for step in 0..2 { -// let (start_s, start_r) = bounded::<()>(0); -// let (end_s, end_r) = bounded::<()>(0); - -// let ((s1, r1), (s2, r2)) = if step == 0 { -// (bounded::<i32>(1), bounded::<i32>(1)) -// } else { -// (unbounded::<i32>(), unbounded::<i32>()) -// }; - -// scope(|scope| { -// scope.spawn(|_| { -// for _ in 0..COUNT { -// start_s.send(()).unwrap(); - -// s1.send(1).unwrap(); -// select! { -// recv(r1) -> _ => {} -// recv(r2) -> _ => {} -// default => unreachable!() -// } - -// end_s.send(()).unwrap(); -// let _ = r2.try_recv(); -// } -// }); - -// for _ in 0..COUNT { -// start_r.recv().unwrap(); - -// s2.send(1).unwrap(); -// let _ = r1.try_recv(); - -// end_r.recv().unwrap(); -// } -// }) -// .unwrap(); -// } -// } - -// #[test] -// fn linearizable_timeout() { -// const COUNT: usize = 100_000; - -// for step in 0..2 { -// let (start_s, start_r) = bounded::<()>(0); -// let (end_s, end_r) = bounded::<()>(0); - -// let ((s1, r1), (s2, r2)) = if step == 0 { -// (bounded::<i32>(1), bounded::<i32>(1)) -// } else { -// (unbounded::<i32>(), unbounded::<i32>()) -// }; - -// scope(|scope| { -// scope.spawn(|_| { -// for _ in 0..COUNT { -// start_s.send(()).unwrap(); - -// s1.send(1).unwrap(); -// select! { -// recv(r1) -> _ => {} -// recv(r2) -> _ => {} -// default(ms(0)) => unreachable!() -// } - -// end_s.send(()).unwrap(); -// let _ = r2.try_recv(); -// } -// }); - -// for _ in 0..COUNT { -// start_r.recv().unwrap(); - -// s2.send(1).unwrap(); -// let _ = r1.try_recv(); - -// end_r.recv().unwrap(); -// } -// }) -// .unwrap(); -// } -// } - -// #[test] -// fn fairness1() { -// const COUNT: usize = 10_000; - -// let (s1, r1) = bounded::<()>(COUNT); -// let (s2, r2) = unbounded::<()>(); - -// for _ in 0..COUNT { -// s1.send(()).unwrap(); -// s2.send(()).unwrap(); -// } - -// let mut hits = [0usize; 4]; -// for _ in 0..COUNT { -// select! { -// recv(r1) -> _ => hits[0] += 1, -// recv(r2) -> _ => hits[1] += 1, -// recv(after(ms(0))) -> _ => hits[2] += 1, -// recv(tick(ms(0))) -> _ => hits[3] += 1, -// } -// } -// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2)); -// } - -// #[test] -// fn fairness2() { -// const COUNT: usize = 10_000; - -// let (s1, r1) = unbounded::<()>(); -// let (s2, r2) = bounded::<()>(1); -// let (s3, r3) = bounded::<()>(0); - -// scope(|scope| { -// scope.spawn(|_| { -// let (hole, _r) = bounded(0); - -// for _ in 0..COUNT { -// let s1 = if s1.is_empty() { &s1 } else { &hole }; -// let s2 = if s2.is_empty() { &s2 } else { &hole }; - -// select! { -// send(s1, ()) -> res => assert!(res.is_ok()), -// send(s2, ()) -> res => assert!(res.is_ok()), -// send(s3, ()) -> res => assert!(res.is_ok()), -// } -// } -// }); - -// let hits = vec![Cell::new(0usize); 3]; -// for _ in 0..COUNT { -// select! { -// recv(r1) -> _ => hits[0].set(hits[0].get() + 1), -// recv(r2) -> _ => hits[1].set(hits[1].get() + 1), -// recv(r3) -> _ => hits[2].set(hits[2].get() + 1), -// } -// } -// assert!(hits.iter().all(|x| x.get() >= COUNT / hits.len() / 50)); -// }) -// .unwrap(); -// } - -// #[test] -// fn fairness_recv() { -// const COUNT: usize = 10_000; - -// let (s1, r1) = bounded::<()>(COUNT); -// let (s2, r2) = unbounded::<()>(); - -// for _ in 0..COUNT { -// s1.send(()).unwrap(); -// s2.send(()).unwrap(); -// } - -// let mut hits = [0usize; 2]; -// while hits[0] + hits[1] < COUNT { -// select! { -// recv(r1) -> _ => hits[0] += 1, -// recv(r2) -> _ => hits[1] += 1, -// } -// } -// assert!(hits.iter().all(|x| *x >= COUNT / 4)); -// } - -// #[test] -// fn fairness_send() { -// const COUNT: usize = 10_000; - -// let (s1, _r1) = bounded::<()>(COUNT); -// let (s2, _r2) = unbounded::<()>(); - -// let mut hits = [0usize; 2]; -// for _ in 0..COUNT { -// select! { -// send(s1, ()) -> _ => hits[0] += 1, -// send(s2, ()) -> _ => hits[1] += 1, -// } -// } -// assert!(hits.iter().all(|x| *x >= COUNT / 4)); -// } - -// #[test] -// fn references() { -// let (s, r) = unbounded::<i32>(); -// select! { -// send(s, 0) -> _ => {} -// recv(r) -> _ => {} -// } -// select! { -// send(&&&&s, 0) -> _ => {} -// recv(&&&&r) -> _ => {} -// } -// select! { -// recv(Some(&r).unwrap_or(&never())) -> _ => {}, -// default => {} -// } -// select! { -// recv(Some(r).unwrap_or(never())) -> _ => {}, -// default => {} -// } -// } - -// #[test] -// fn case_blocks() { -// let (s, r) = unbounded::<i32>(); - -// select! { -// recv(r) -> _ => 3.0, -// recv(r) -> _ => loop { -// unreachable!() -// }, -// recv(r) -> _ => match 7 + 3 { -// _ => unreachable!() -// }, -// default => 7. -// }; - -// select! { -// recv(r) -> msg => if msg.is_ok() { -// unreachable!() -// }, -// default => () -// } - -// drop(s); -// } - -// #[test] -// fn move_handles() { -// let (s, r) = unbounded::<i32>(); -// select! { -// recv((move || r)()) -> _ => {} -// send((move || s)(), 0) -> _ => {} -// } -// } - -// #[test] -// fn infer_types() { -// let (s, r) = unbounded(); -// select! { -// recv(r) -> _ => {} -// default => {} -// } -// s.send(()).unwrap(); - -// let (s, r) = unbounded(); -// select! { -// send(s, ()) -> _ => {} -// } -// r.recv().unwrap(); -// } - -// #[test] -// fn default_syntax() { -// let (s, r) = bounded::<i32>(0); - -// select! { -// recv(r) -> _ => panic!(), -// default => {} -// } -// select! { -// send(s, 0) -> _ => panic!(), -// default() => {} -// } -// select! { -// default => {} -// } -// select! { -// default() => {} -// } -// } - -// #[test] -// fn same_variable_name() { -// let (_, r) = unbounded::<i32>(); -// select! { -// recv(r) -> r => assert!(r.is_err()), -// } -// } - -// #[test] -// fn handles_on_heap() { -// let (s, r) = unbounded::<i32>(); -// let (s, r) = (Box::new(s), Box::new(r)); - -// select! { -// send(*s, 0) -> _ => {} -// recv(*r) -> _ => {} -// default => {} -// } - -// drop(s); -// drop(r); -// } - -// #[test] -// fn once_blocks() { -// let (s, r) = unbounded::<i32>(); - -// let once = Box::new(()); -// select! { -// send(s, 0) -> _ => drop(once), -// } - -// let once = Box::new(()); -// select! { -// recv(r) -> _ => drop(once), -// } - -// let once1 = Box::new(()); -// let once2 = Box::new(()); -// select! { -// send(s, 0) -> _ => drop(once1), -// default => drop(once2), -// } - -// let once1 = Box::new(()); -// let once2 = Box::new(()); -// select! { -// recv(r) -> _ => drop(once1), -// default => drop(once2), -// } - -// let once1 = Box::new(()); -// let once2 = Box::new(()); -// select! { -// recv(r) -> _ => drop(once1), -// send(s, 0) -> _ => drop(once2), -// } -// } - -// #[test] -// fn once_receiver() { -// let (_, r) = unbounded::<i32>(); - -// let once = Box::new(()); -// let get = move || { -// drop(once); -// r -// }; - -// select! { -// recv(get()) -> _ => {} -// } -// } - -// #[test] -// fn once_sender() { -// let (s, _) = unbounded::<i32>(); - -// let once = Box::new(()); -// let get = move || { -// drop(once); -// s -// }; - -// select! { -// send(get(), 5) -> _ => {} -// } -// } - -// #[test] -// fn parse_nesting() { -// let (_, r) = unbounded::<i32>(); - -// select! { -// recv(r) -> _ => {} -// recv(r) -> _ => { -// select! { -// recv(r) -> _ => {} -// recv(r) -> _ => { -// select! { -// recv(r) -> _ => {} -// recv(r) -> _ => { -// select! { -// default => {} -// } -// } -// } -// } -// } -// } -// } -// } - -// #[test] -// fn evaluate() { -// let (s, r) = unbounded::<i32>(); - -// let v = select! { -// recv(r) -> _ => "foo".into(), -// send(s, 0) -> _ => "bar".to_owned(), -// default => "baz".to_string(), -// }; -// assert_eq!(v, "bar"); - -// let v = select! { -// recv(r) -> _ => "foo".into(), -// default => "baz".to_string(), -// }; -// assert_eq!(v, "foo"); - -// let v = select! { -// recv(r) -> _ => "foo".into(), -// default => "baz".to_string(), -// }; -// assert_eq!(v, "baz"); -// } - -// #[test] -// fn deref() { -// use crossbeam_channel as cc; - -// struct Sender<T>(cc::Sender<T>); -// struct Receiver<T>(cc::Receiver<T>); - -// impl<T> Deref for Receiver<T> { -// type Target = cc::Receiver<T>; - -// fn deref(&self) -> &Self::Target { -// &self.0 -// } -// } - -// impl<T> Deref for Sender<T> { -// type Target = cc::Sender<T>; - -// fn deref(&self) -> &Self::Target { -// &self.0 -// } -// } - -// let (s, r) = bounded::<i32>(0); -// let (s, r) = (Sender(s), Receiver(r)); - -// select! { -// send(s, 0) -> _ => panic!(), -// recv(r) -> _ => panic!(), -// default => {} -// } -// } - -// #[test] -// fn result_types() { -// let (s, _) = bounded::<i32>(0); -// let (_, r) = bounded::<i32>(0); - -// select! { -// recv(r) -> res => drop::<Result<i32, RecvError>>(res), -// } -// select! { -// recv(r) -> res => drop::<Result<i32, RecvError>>(res), -// default => {} -// } -// select! { -// recv(r) -> res => drop::<Result<i32, RecvError>>(res), -// default(ms(0)) => {} -// } - -// select! { -// send(s, 0) -> res => drop::<Result<(), SendError<i32>>>(res), -// } -// select! { -// send(s, 0) -> res => drop::<Result<(), SendError<i32>>>(res), -// default => {} -// } -// select! { -// send(s, 0) -> res => drop::<Result<(), SendError<i32>>>(res), -// default(ms(0)) => {} -// } - -// select! { -// send(s, 0) -> res => drop::<Result<(), SendError<i32>>>(res), -// recv(r) -> res => drop::<Result<i32, RecvError>>(res), -// } -// } - -// #[test] -// fn try_recv() { -// let (s, r) = bounded(0); - -// scope(|scope| { -// scope.spawn(move |_| { -// select! { -// recv(r) -> _ => panic!(), -// default => {} -// } -// thread::sleep(ms(1500)); -// select! { -// recv(r) -> v => assert_eq!(v, Ok(7)), -// default => panic!(), -// } -// thread::sleep(ms(500)); -// select! { -// recv(r) -> v => assert_eq!(v, Err(RecvError)), -// default => panic!(), -// } -// }); -// scope.spawn(move |_| { -// thread::sleep(ms(1000)); -// select! { -// send(s, 7) -> res => res.unwrap(), -// } -// }); -// }) -// .unwrap(); -// } - -// #[test] -// fn recv() { -// let (s, r) = bounded(0); - -// scope(|scope| { -// scope.spawn(move |_| { -// select! { -// recv(r) -> v => assert_eq!(v, Ok(7)), -// } -// thread::sleep(ms(1000)); -// select! { -// recv(r) -> v => assert_eq!(v, Ok(8)), -// } -// thread::sleep(ms(1000)); -// select! { -// recv(r) -> v => assert_eq!(v, Ok(9)), -// } -// select! { -// recv(r) -> v => assert_eq!(v, Err(RecvError)), -// } -// }); -// scope.spawn(move |_| { -// thread::sleep(ms(1500)); -// select! { -// send(s, 7) -> res => res.unwrap(), -// } -// select! { -// send(s, 8) -> res => res.unwrap(), -// } -// select! { -// send(s, 9) -> res => res.unwrap(), -// } -// }); -// }) -// .unwrap(); -// } - -// #[test] -// fn recv_timeout() { -// let (s, r) = bounded::<i32>(0); - -// scope(|scope| { -// scope.spawn(move |_| { -// select! { -// recv(r) -> _ => panic!(), -// default(ms(1000)) => {} -// } -// select! { -// recv(r) -> v => assert_eq!(v, Ok(7)), -// default(ms(1000)) => panic!(), -// } -// select! { -// recv(r) -> v => assert_eq!(v, Err(RecvError)), -// default(ms(1000)) => panic!(), -// } -// }); -// scope.spawn(move |_| { -// thread::sleep(ms(1500)); -// select! { -// send(s, 7) -> res => res.unwrap(), -// } -// }); -// }) -// .unwrap(); -// } - -// #[test] -// fn try_send() { -// let (s, r) = bounded(0); - -// scope(|scope| { -// scope.spawn(move |_| { -// select! { -// send(s, 7) -> _ => panic!(), -// default => {} -// } -// thread::sleep(ms(1500)); -// select! { -// send(s, 8) -> res => res.unwrap(), -// default => panic!(), -// } -// thread::sleep(ms(500)); -// select! { -// send(s, 8) -> res => assert_eq!(res, Err(SendError(8))), -// default => panic!(), -// } -// }); -// scope.spawn(move |_| { -// thread::sleep(ms(1000)); -// select! { -// recv(r) -> v => assert_eq!(v, Ok(8)), -// } -// }); -// }) -// .unwrap(); -// } - -// #[test] -// fn send() { -// let (s, r) = bounded(0); - -// scope(|scope| { -// scope.spawn(move |_| { -// select! { -// send(s, 7) -> res => res.unwrap(), -// } -// thread::sleep(ms(1000)); -// select! { -// send(s, 8) -> res => res.unwrap(), -// } -// thread::sleep(ms(1000)); -// select! { -// send(s, 9) -> res => res.unwrap(), -// } -// }); -// scope.spawn(move |_| { -// thread::sleep(ms(1500)); -// select! { -// recv(r) -> v => assert_eq!(v, Ok(7)), -// } -// select! { -// recv(r) -> v => assert_eq!(v, Ok(8)), -// } -// select! { -// recv(r) -> v => assert_eq!(v, Ok(9)), -// } -// }); -// }) -// .unwrap(); -// } - -// #[test] -// fn send_timeout() { -// let (s, r) = bounded(0); - -// scope(|scope| { -// scope.spawn(move |_| { -// select! { -// send(s, 7) -> _ => panic!(), -// default(ms(1000)) => {} -// } -// select! { -// send(s, 8) -> res => res.unwrap(), -// default(ms(1000)) => panic!(), -// } -// select! { -// send(s, 9) -> res => assert_eq!(res, Err(SendError(9))), -// default(ms(1000)) => panic!(), -// } -// }); -// scope.spawn(move |_| { -// thread::sleep(ms(1500)); -// select! { -// recv(r) -> v => assert_eq!(v, Ok(8)), -// } -// }); -// }) -// .unwrap(); -// } - -// #[test] -// fn disconnect_wakes_sender() { -// let (s, r) = bounded(0); - -// scope(|scope| { -// scope.spawn(move |_| { -// select! { -// send(s, ()) -> res => assert_eq!(res, Err(SendError(()))), -// } -// }); -// scope.spawn(move |_| { -// thread::sleep(ms(1000)); -// drop(r); -// }); -// }) -// .unwrap(); -// } - -// #[test] -// fn disconnect_wakes_receiver() { -// let (s, r) = bounded::<()>(0); - -// scope(|scope| { -// scope.spawn(move |_| { -// select! { -// recv(r) -> res => assert_eq!(res, Err(RecvError)), -// } -// }); -// scope.spawn(move |_| { -// thread::sleep(ms(1000)); -// drop(s); -// }); -// }) -// .unwrap(); -// } diff --git a/vendor/flume/tests/stream.rs b/vendor/flume/tests/stream.rs deleted file mode 100644 index e3b32cd..0000000 --- a/vendor/flume/tests/stream.rs +++ /dev/null @@ -1,255 +0,0 @@ -#[cfg(feature = "async")] -use { - flume::*, - futures::{stream::FuturesUnordered, StreamExt, TryFutureExt}, - async_std::prelude::FutureExt, - std::time::Duration, -}; -use futures::{stream, Stream}; - -#[cfg(feature = "async")] -#[test] -fn stream_recv() { - let (tx, rx) = unbounded(); - - let t = std::thread::spawn(move || { - std::thread::sleep(std::time::Duration::from_millis(250)); - tx.send(42u32).unwrap(); - println!("sent"); - }); - - async_std::task::block_on(async { - println!("receiving..."); - let x = rx.stream().next().await; - println!("received"); - assert_eq!(x, Some(42)); - }); - - t.join().unwrap(); -} - -#[cfg(feature = "async")] -#[test] -fn stream_recv_disconnect() { - let (tx, rx) = bounded::<i32>(0); - - let t = std::thread::spawn(move || { - tx.send(42); - std::thread::sleep(std::time::Duration::from_millis(250)); - drop(tx) - }); - - async_std::task::block_on(async { - let mut stream = rx.into_stream(); - assert_eq!(stream.next().await, Some(42)); - assert_eq!(stream.next().await, None); - }); - - t.join().unwrap(); -} - -#[cfg(feature = "async")] -#[test] -fn stream_recv_drop_recv() { - let (tx, rx) = bounded::<i32>(10); - - let rx2 = rx.clone(); - let mut stream = rx.into_stream(); - - async_std::task::block_on(async { - let res = async_std::future::timeout( - std::time::Duration::from_millis(500), - stream.next() - ).await; - - assert!(res.is_err()); - }); - - let t = std::thread::spawn(move || { - async_std::task::block_on(async { - rx2.stream().next().await - }) - }); - - std::thread::sleep(std::time::Duration::from_millis(500)); - - tx.send(42).unwrap(); - - drop(stream); - - assert_eq!(t.join().unwrap(), Some(42)) -} - -#[cfg(feature = "async")] -#[test] -fn r#stream_drop_send_disconnect() { - let (tx, rx) = bounded::<i32>(1); - - let t = std::thread::spawn(move || { - std::thread::sleep(std::time::Duration::from_millis(250)); - drop(tx); - }); - - async_std::task::block_on(async { - let mut stream = rx.into_stream(); - assert_eq!(stream.next().await, None); - }); - - t.join().unwrap(); -} - -#[cfg(feature = "async")] -#[async_std::test] -async fn stream_send_1_million_no_drop_or_reorder() { - #[derive(Debug)] - enum Message { - Increment { - old: u64, - }, - ReturnCount, - } - - let (tx, rx) = unbounded(); - - let t = async_std::task::spawn(async move { - let mut count = 0u64; - let mut stream = rx.into_stream(); - - while let Some(Message::Increment { old }) = stream.next().await { - assert_eq!(old, count); - count += 1; - } - - count - }); - - for next in 0..1_000_000 { - tx.send(Message::Increment { old: next }).unwrap(); - } - - tx.send(Message::ReturnCount).unwrap(); - - let count = t.await; - assert_eq!(count, 1_000_000) -} - -#[cfg(feature = "async")] -#[async_std::test] -async fn parallel_streams_and_async_recv() { - let (tx, rx) = flume::unbounded(); - let rx = ℞ - let send_fut = async move { - let n_sends: usize = 100000; - for _ in 0..n_sends { - tx.send_async(()).await.unwrap(); - } - }; - - async_std::task::spawn( - send_fut - .timeout(Duration::from_secs(5)) - .map_err(|_| panic!("Send timed out!")) - ); - - let mut futures_unordered = (0..250) - .map(|n| async move { - if n % 2 == 0 { - let mut stream = rx.stream(); - while let Some(()) = stream.next().await {} - } else { - while let Ok(()) = rx.recv_async().await {} - } - - }) - .collect::<FuturesUnordered<_>>(); - - let recv_fut = async { - while futures_unordered.next().await.is_some() {} - }; - - recv_fut - .timeout(Duration::from_secs(5)) - .map_err(|_| panic!("Receive timed out!")) - .await - .unwrap(); -} - -#[cfg(feature = "async")] -#[test] -fn stream_no_double_wake() { - use std::sync::atomic::{AtomicUsize, Ordering}; - use std::sync::Arc; - use std::pin::Pin; - use std::task::Context; - use futures::task::{waker, ArcWake}; - use futures::Stream; - - let count = Arc::new(AtomicUsize::new(0)); - - // all this waker does is count how many times it is called - struct CounterWaker { - count: Arc<AtomicUsize>, - } - - impl ArcWake for CounterWaker { - fn wake_by_ref(arc_self: &Arc<Self>) { - arc_self.count.fetch_add(1, Ordering::SeqCst); - } - } - - // create waker and context - let w = CounterWaker { - count: count.clone(), - }; - let w = waker(Arc::new(w)); - let cx = &mut Context::from_waker(&w); - - // create unbounded channel - let (tx, rx) = unbounded::<()>(); - let mut stream = rx.stream(); - - // register waker with stream - let _ = Pin::new(&mut stream).poll_next(cx); - - // send multiple items - tx.send(()).unwrap(); - tx.send(()).unwrap(); - tx.send(()).unwrap(); - - // verify that stream is only woken up once. - assert_eq!(count.load(Ordering::SeqCst), 1); -} - -#[cfg(feature = "async")] -#[async_std::test] -async fn stream_forward_issue_55() { // https://github.com/zesterer/flume/issues/55 - fn dummy_stream() -> impl Stream<Item = usize> { - stream::unfold(0, |count| async move { - if count < 1000 { - Some((count, count + 1)) - } else { - None - } - }) - } - - let (send_task, recv_task) = { - use futures::SinkExt; - let (tx, rx) = flume::bounded(100); - - let send_task = dummy_stream() - .map(|i| Ok(i)) - .forward(tx.into_sink().sink_map_err(|e| { - panic!("send error:{:#?}", e) - })); - - let recv_task = rx - .into_stream() - .for_each(|item| async move {}); - (send_task, recv_task) - }; - - let jh = async_std::task::spawn(send_task); - async_std::task::block_on(recv_task); - jh.await.unwrap(); -} diff --git a/vendor/flume/tests/thread_locals.rs b/vendor/flume/tests/thread_locals.rs deleted file mode 100644 index acde751..0000000 --- a/vendor/flume/tests/thread_locals.rs +++ /dev/null @@ -1,53 +0,0 @@ -// //! Tests that make sure accessing thread-locals while exiting the thread doesn't cause panics. - -// extern crate crossbeam_utils; - -// use std::thread; -// use std::time::Duration; - -// use flume::unbounded; -// use crossbeam_utils::thread::scope; - -// fn ms(ms: u64) -> Duration { -// Duration::from_millis(ms) -// } - -// #[test] -// #[cfg_attr(target_os = "macos", ignore = "TLS is destroyed too early on macOS")] -// fn use_while_exiting() { -// struct Foo; - -// impl Drop for Foo { -// fn drop(&mut self) { -// // A blocking operation after the thread-locals have been dropped. This will attempt to -// // use the thread-locals and must not panic. -// let (_s, r) = unbounded::<()>(); -// select! { -// recv(r) -> _ => {} -// default(ms(100)) => {} -// } -// } -// } - -// thread_local! { -// static FOO: Foo = Foo; -// } - -// let (s, r) = unbounded::<()>(); - -// scope(|scope| { -// scope.spawn(|_| { -// // First initialize `FOO`, then the thread-locals related to crossbeam-channel. -// FOO.with(|_| ()); -// r.recv().unwrap(); -// // At thread exit, thread-locals related to crossbeam-channel get dropped first and -// // `FOO` is dropped last. -// }); - -// scope.spawn(|_| { -// thread::sleep(ms(100)); -// s.send(()).unwrap(); -// }); -// }) -// .unwrap(); -// } diff --git a/vendor/flume/tests/tick.rs b/vendor/flume/tests/tick.rs deleted file mode 100644 index b0fcd44..0000000 --- a/vendor/flume/tests/tick.rs +++ /dev/null @@ -1,353 +0,0 @@ -// //! Tests for the tick channel flavor. - -// #[macro_use] -// extern crate crossbeam_channel; -// extern crate crossbeam_utils; -// extern crate rand; - -// use std::sync::atomic::AtomicUsize; -// use std::sync::atomic::Ordering; -// use std::thread; -// use std::time::{Duration, Instant}; - -// use crossbeam_channel::{after, tick, Select, TryRecvError}; -// use crossbeam_utils::thread::scope; - -// fn ms(ms: u64) -> Duration { -// Duration::from_millis(ms) -// } - -// #[test] -// fn fire() { -// let start = Instant::now(); -// let r = tick(ms(50)); - -// assert_eq!(r.try_recv(), Err(TryRecvError::Empty)); -// thread::sleep(ms(100)); - -// let fired = r.try_recv().unwrap(); -// assert!(start < fired); -// assert!(fired - start >= ms(50)); - -// let now = Instant::now(); -// assert!(fired < now); -// assert!(now - fired >= ms(50)); - -// assert_eq!(r.try_recv(), Err(TryRecvError::Empty)); - -// select! { -// recv(r) -> _ => panic!(), -// default => {} -// } - -// select! { -// recv(r) -> _ => {} -// recv(tick(ms(200))) -> _ => panic!(), -// } -// } - -// #[test] -// fn intervals() { -// let start = Instant::now(); -// let r = tick(ms(50)); - -// let t1 = r.recv().unwrap(); -// assert!(start + ms(50) <= t1); -// assert!(start + ms(100) > t1); - -// thread::sleep(ms(300)); -// let t2 = r.try_recv().unwrap(); -// assert!(start + ms(100) <= t2); -// assert!(start + ms(150) > t2); - -// assert_eq!(r.try_recv(), Err(TryRecvError::Empty)); -// let t3 = r.recv().unwrap(); -// assert!(start + ms(400) <= t3); -// assert!(start + ms(450) > t3); - -// assert_eq!(r.try_recv(), Err(TryRecvError::Empty)); -// } - -// #[test] -// fn capacity() { -// const COUNT: usize = 10; - -// for i in 0..COUNT { -// let r = tick(ms(i as u64)); -// assert_eq!(r.capacity(), Some(1)); -// } -// } - -// #[test] -// fn len_empty_full() { -// let r = tick(ms(50)); - -// assert_eq!(r.len(), 0); -// assert_eq!(r.is_empty(), true); -// assert_eq!(r.is_full(), false); - -// thread::sleep(ms(100)); - -// assert_eq!(r.len(), 1); -// assert_eq!(r.is_empty(), false); -// assert_eq!(r.is_full(), true); - -// r.try_recv().unwrap(); - -// assert_eq!(r.len(), 0); -// assert_eq!(r.is_empty(), true); -// assert_eq!(r.is_full(), false); -// } - -// #[test] -// fn try_recv() { -// let r = tick(ms(200)); -// assert!(r.try_recv().is_err()); - -// thread::sleep(ms(100)); -// assert!(r.try_recv().is_err()); - -// thread::sleep(ms(200)); -// assert!(r.try_recv().is_ok()); -// assert!(r.try_recv().is_err()); - -// thread::sleep(ms(200)); -// assert!(r.try_recv().is_ok()); -// assert!(r.try_recv().is_err()); -// } - -// #[test] -// fn recv() { -// let start = Instant::now(); -// let r = tick(ms(50)); - -// let fired = r.recv().unwrap(); -// assert!(start < fired); -// assert!(fired - start >= ms(50)); - -// let now = Instant::now(); -// assert!(fired < now); -// assert!(now - fired < fired - start); - -// assert_eq!(r.try_recv(), Err(TryRecvError::Empty)); -// } - -// #[test] -// fn recv_timeout() { -// let start = Instant::now(); -// let r = tick(ms(200)); - -// assert!(r.recv_timeout(ms(100)).is_err()); -// let now = Instant::now(); -// assert!(now - start >= ms(100)); -// assert!(now - start <= ms(150)); - -// let fired = r.recv_timeout(ms(200)).unwrap(); -// assert!(fired - start >= ms(200)); -// assert!(fired - start <= ms(250)); - -// assert!(r.recv_timeout(ms(100)).is_err()); -// let now = Instant::now(); -// assert!(now - start >= ms(300)); -// assert!(now - start <= ms(350)); - -// let fired = r.recv_timeout(ms(200)).unwrap(); -// assert!(fired - start >= ms(400)); -// assert!(fired - start <= ms(450)); -// } - -// #[test] -// fn recv_two() { -// let r1 = tick(ms(50)); -// let r2 = tick(ms(50)); - -// scope(|scope| { -// scope.spawn(|_| { -// for _ in 0..10 { -// select! { -// recv(r1) -> _ => {} -// recv(r2) -> _ => {} -// } -// } -// }); -// scope.spawn(|_| { -// for _ in 0..10 { -// select! { -// recv(r1) -> _ => {} -// recv(r2) -> _ => {} -// } -// } -// }); -// }) -// .unwrap(); -// } - -// #[test] -// fn recv_race() { -// select! { -// recv(tick(ms(50))) -> _ => {} -// recv(tick(ms(100))) -> _ => panic!(), -// } - -// select! { -// recv(tick(ms(100))) -> _ => panic!(), -// recv(tick(ms(50))) -> _ => {} -// } -// } - -// #[test] -// fn stress_default() { -// const COUNT: usize = 10; - -// for _ in 0..COUNT { -// select! { -// recv(tick(ms(0))) -> _ => {} -// default => panic!(), -// } -// } - -// for _ in 0..COUNT { -// select! { -// recv(tick(ms(100))) -> _ => panic!(), -// default => {} -// } -// } -// } - -// #[test] -// fn select() { -// const THREADS: usize = 4; - -// let hits = AtomicUsize::new(0); -// let r1 = tick(ms(200)); -// let r2 = tick(ms(300)); - -// scope(|scope| { -// for _ in 0..THREADS { -// scope.spawn(|_| { -// let timeout = after(ms(1100)); -// loop { -// let mut sel = Select::new(); -// let oper1 = sel.recv(&r1); -// let oper2 = sel.recv(&r2); -// let oper3 = sel.recv(&timeout); -// let oper = sel.select(); -// match oper.index() { -// i if i == oper1 => { -// oper.recv(&r1).unwrap(); -// hits.fetch_add(1, Ordering::SeqCst); -// } -// i if i == oper2 => { -// oper.recv(&r2).unwrap(); -// hits.fetch_add(1, Ordering::SeqCst); -// } -// i if i == oper3 => { -// oper.recv(&timeout).unwrap(); -// break; -// } -// _ => unreachable!(), -// } -// } -// }); -// } -// }) -// .unwrap(); - -// assert_eq!(hits.load(Ordering::SeqCst), 8); -// } - -// #[test] -// fn ready() { -// const THREADS: usize = 4; - -// let hits = AtomicUsize::new(0); -// let r1 = tick(ms(200)); -// let r2 = tick(ms(300)); - -// scope(|scope| { -// for _ in 0..THREADS { -// scope.spawn(|_| { -// let timeout = after(ms(1100)); -// 'outer: loop { -// let mut sel = Select::new(); -// sel.recv(&r1); -// sel.recv(&r2); -// sel.recv(&timeout); -// loop { -// match sel.ready() { -// 0 => { -// if r1.try_recv().is_ok() { -// hits.fetch_add(1, Ordering::SeqCst); -// break; -// } -// } -// 1 => { -// if r2.try_recv().is_ok() { -// hits.fetch_add(1, Ordering::SeqCst); -// break; -// } -// } -// 2 => { -// if timeout.try_recv().is_ok() { -// break 'outer; -// } -// } -// _ => unreachable!(), -// } -// } -// } -// }); -// } -// }) -// .unwrap(); - -// assert_eq!(hits.load(Ordering::SeqCst), 8); -// } - -// #[test] -// fn fairness() { -// const COUNT: usize = 30; - -// for &dur in &[0, 1] { -// let mut hits = [0usize; 2]; - -// for _ in 0..COUNT { -// let r1 = tick(ms(dur)); -// let r2 = tick(ms(dur)); - -// for _ in 0..COUNT { -// select! { -// recv(r1) -> _ => hits[0] += 1, -// recv(r2) -> _ => hits[1] += 1, -// } -// } -// } - -// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2)); -// } -// } - -// #[test] -// fn fairness_duplicates() { -// const COUNT: usize = 30; - -// for &dur in &[0, 1] { -// let mut hits = [0usize; 5]; - -// for _ in 0..COUNT { -// let r = tick(ms(dur)); - -// for _ in 0..COUNT { -// select! { -// recv(r) -> _ => hits[0] += 1, -// recv(r) -> _ => hits[1] += 1, -// recv(r) -> _ => hits[2] += 1, -// recv(r) -> _ => hits[3] += 1, -// recv(r) -> _ => hits[4] += 1, -// } -// } -// } - -// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2)); -// } -// } diff --git a/vendor/flume/tests/zero.rs b/vendor/flume/tests/zero.rs deleted file mode 100644 index be4239d..0000000 --- a/vendor/flume/tests/zero.rs +++ /dev/null @@ -1,557 +0,0 @@ -//! Tests for the zero channel flavor. - -extern crate crossbeam_utils; -extern crate rand; - -use std::any::Any; -use std::sync::atomic::AtomicUsize; -use std::sync::atomic::Ordering; -use std::thread; -use std::time::Duration; - -use flume::{bounded, Receiver}; -use flume::{RecvError, RecvTimeoutError, TryRecvError}; -use flume::{SendError, SendTimeoutError, TrySendError}; -use crossbeam_utils::thread::scope; -use rand::{thread_rng, Rng}; - -fn ms(ms: u64) -> Duration { - Duration::from_millis(ms) -} - -#[test] -fn smoke() { - let (s, r) = bounded(0); - assert_eq!(s.try_send(7), Err(TrySendError::Full(7))); - assert_eq!(r.try_recv(), Err(TryRecvError::Empty)); -} - -#[test] -fn capacity() { - let (s, r) = bounded::<()>(0); - assert_eq!(s.capacity(), Some(0)); - assert_eq!(r.capacity(), Some(0)); -} - -#[test] -fn len_empty_full() { - let (s, r) = bounded(0); - - assert_eq!(s.len(), 0); - assert_eq!(s.is_empty(), true); - assert_eq!(s.is_full(), true); - assert_eq!(r.len(), 0); - assert_eq!(r.is_empty(), true); - assert_eq!(r.is_full(), true); - - scope(|scope| { - scope.spawn(|_| s.send(0).unwrap()); - scope.spawn(|_| r.recv().unwrap()); - }) - .unwrap(); - - assert_eq!(s.len(), 0); - assert_eq!(s.is_empty(), true); - assert_eq!(s.is_full(), true); - assert_eq!(r.len(), 0); - assert_eq!(r.is_empty(), true); - assert_eq!(r.is_full(), true); -} - -#[test] -fn try_recv() { - let (s, r) = bounded(0); - - scope(|scope| { - scope.spawn(move |_| { - assert_eq!(r.try_recv(), Err(TryRecvError::Empty)); - thread::sleep(ms(1500)); - assert_eq!(r.try_recv(), Ok(7)); - thread::sleep(ms(500)); - assert_eq!(r.try_recv(), Err(TryRecvError::Disconnected)); - }); - scope.spawn(move |_| { - thread::sleep(ms(1000)); - s.send(7).unwrap(); - }); - }) - .unwrap(); -} - -#[test] -fn recv() { - let (s, r) = bounded(0); - - scope(|scope| { - scope.spawn(move |_| { - assert_eq!(r.recv(), Ok(7)); - thread::sleep(ms(1000)); - assert_eq!(r.recv(), Ok(8)); - thread::sleep(ms(1000)); - assert_eq!(r.recv(), Ok(9)); - assert!(r.recv().is_err()); - }); - scope.spawn(move |_| { - thread::sleep(ms(1500)); - s.send(7).unwrap(); - s.send(8).unwrap(); - s.send(9).unwrap(); - }); - }) - .unwrap(); -} - -#[test] -fn recv_timeout() { - let (s, r) = bounded::<i32>(0); - - scope(|scope| { - scope.spawn(move |_| { - assert_eq!(r.recv_timeout(ms(1000)), Err(RecvTimeoutError::Timeout)); - assert_eq!(r.recv_timeout(ms(1000)), Ok(7)); - assert_eq!( - r.recv_timeout(ms(1000)), - Err(RecvTimeoutError::Disconnected) - ); - }); - scope.spawn(move |_| { - thread::sleep(ms(1500)); - s.send(7).unwrap(); - }); - }) - .unwrap(); -} - -#[test] -fn try_send() { - let (s, r) = bounded(0); - - scope(|scope| { - scope.spawn(move |_| { - assert_eq!(s.try_send(7), Err(TrySendError::Full(7))); - thread::sleep(ms(1500)); - assert_eq!(s.try_send(8), Ok(())); - thread::sleep(ms(500)); - assert_eq!(s.try_send(9), Err(TrySendError::Disconnected(9))); - }); - scope.spawn(move |_| { - thread::sleep(ms(1000)); - assert_eq!(r.recv(), Ok(8)); - }); - }) - .unwrap(); -} - -#[test] -fn send() { - let (s, r) = bounded(0); - - scope(|scope| { - scope.spawn(move |_| { - s.send(7).unwrap(); - thread::sleep(ms(1000)); - s.send(8).unwrap(); - thread::sleep(ms(1000)); - s.send(9).unwrap(); - }); - scope.spawn(move |_| { - thread::sleep(ms(1500)); - assert_eq!(r.recv(), Ok(7)); - assert_eq!(r.recv(), Ok(8)); - assert_eq!(r.recv(), Ok(9)); - }); - }) - .unwrap(); -} - -#[test] -fn send_timeout() { - let (s, r) = bounded(0); - - scope(|scope| { - scope.spawn(move |_| { - assert_eq!( - s.send_timeout(7, ms(1000)), - Err(SendTimeoutError::Timeout(7)) - ); - assert_eq!(s.send_timeout(8, ms(1000)), Ok(())); - assert_eq!( - s.send_timeout(9, ms(1000)), - Err(SendTimeoutError::Disconnected(9)) - ); - }); - scope.spawn(move |_| { - thread::sleep(ms(1500)); - assert_eq!(r.recv(), Ok(8)); - }); - }) - .unwrap(); -} - -#[test] -fn len() { - const COUNT: usize = 25_000; - - let (s, r) = bounded(0); - - assert_eq!(s.len(), 0); - assert_eq!(r.len(), 0); - - scope(|scope| { - scope.spawn(|_| { - for i in 0..COUNT { - assert_eq!(r.recv(), Ok(i)); - assert_eq!(r.len(), 0); - } - }); - - scope.spawn(|_| { - for i in 0..COUNT { - s.send(i).unwrap(); - assert_eq!(s.len(), 0); - } - }); - }) - .unwrap(); - - assert_eq!(s.len(), 0); - assert_eq!(r.len(), 0); -} - -#[test] -fn disconnect_wakes_sender() { - let (s, r) = bounded(0); - - scope(|scope| { - scope.spawn(move |_| { - assert_eq!(s.send(()), Err(SendError(()))); - }); - scope.spawn(move |_| { - thread::sleep(ms(1000)); - drop(r); - }); - }) - .unwrap(); -} - -#[test] -fn disconnect_wakes_receiver() { - let (s, r) = bounded::<()>(0); - - scope(|scope| { - scope.spawn(move |_| { - assert!(r.recv().is_err()); - }); - scope.spawn(move |_| { - thread::sleep(ms(1000)); - drop(s); - }); - }) - .unwrap(); -} - -#[test] -fn spsc() { - const COUNT: usize = 100_000; - - let (s, r) = bounded(0); - - scope(|scope| { - scope.spawn(move |_| { - for i in 0..COUNT { - assert_eq!(r.recv(), Ok(i)); - } - assert!(r.recv().is_err()); - }); - scope.spawn(move |_| { - for i in 0..COUNT { - s.send(i).unwrap(); - } - }); - }) - .unwrap(); -} - -#[test] -fn mpmc() { - const COUNT: usize = 25_000; - const THREADS: usize = 4; - - let (s, r) = bounded::<usize>(0); - let v = (0..COUNT).map(|_| AtomicUsize::new(0)).collect::<Vec<_>>(); - - scope(|scope| { - for _ in 0..THREADS { - scope.spawn(|_| { - for _ in 0..COUNT { - let n = r.recv().unwrap(); - v[n].fetch_add(1, Ordering::SeqCst); - } - }); - } - for _ in 0..THREADS { - scope.spawn(|_| { - for i in 0..COUNT { - s.send(i).unwrap(); - } - }); - } - }) - .unwrap(); - - for c in v { - assert_eq!(c.load(Ordering::SeqCst), THREADS); - } -} - -#[test] -fn stress_oneshot() { - const COUNT: usize = 10_000; - - for _ in 0..COUNT { - let (s, r) = bounded(1); - - scope(|scope| { - scope.spawn(|_| r.recv().unwrap()); - scope.spawn(|_| s.send(0).unwrap()); - }) - .unwrap(); - } -} - -#[test] -fn stress_iter() { - const COUNT: usize = 1000; - - let (request_s, request_r) = bounded(0); - let (response_s, response_r) = bounded(0); - - scope(|scope| { - scope.spawn(move |_| { - let mut count = 0; - loop { - for x in response_r.try_iter() { - count += x; - if count == COUNT { - return; - } - } - let _ = request_s.try_send(()); - } - }); - - for _ in request_r.iter() { - if response_s.send(1).is_err() { - break; - } - } - }) - .unwrap(); -} - -#[test] -fn stress_timeout_two_threads() { - const COUNT: usize = 100; - - let (s, r) = bounded(0); - - scope(|scope| { - scope.spawn(|_| { - for i in 0..COUNT { - if i % 2 == 0 { - thread::sleep(ms(50)); - } - loop { - if let Ok(()) = s.send_timeout(i, ms(10)) { - break; - } - } - } - }); - - scope.spawn(|_| { - for i in 0..COUNT { - if i % 2 == 0 { - thread::sleep(ms(50)); - } - loop { - if let Ok(x) = r.recv_timeout(ms(10)) { - assert_eq!(x, i); - break; - } - } - } - }); - }) - .unwrap(); -} - -#[test] -fn drops() { - static DROPS: AtomicUsize = AtomicUsize::new(0); - - #[derive(Debug, PartialEq)] - struct DropCounter; - - impl Drop for DropCounter { - fn drop(&mut self) { - DROPS.fetch_add(1, Ordering::SeqCst); - } - } - - let mut rng = thread_rng(); - - for _ in 0..100 { - let steps = rng.gen_range(0..3_000); - - DROPS.store(0, Ordering::SeqCst); - let (s, r) = bounded::<DropCounter>(0); - - scope(|scope| { - scope.spawn(|_| { - for _ in 0..steps { - r.recv().unwrap(); - } - }); - - scope.spawn(|_| { - for _ in 0..steps { - s.send(DropCounter).unwrap(); - } - }); - }) - .unwrap(); - - assert_eq!(DROPS.load(Ordering::SeqCst), steps); - drop(s); - drop(r); - assert_eq!(DROPS.load(Ordering::SeqCst), steps); - } -} - -// #[test] -// fn fairness() { -// const COUNT: usize = 10_000; - -// let (s1, r1) = bounded::<()>(0); -// let (s2, r2) = bounded::<()>(0); - -// scope(|scope| { -// scope.spawn(|_| { -// let mut hits = [0usize; 2]; -// for _ in 0..COUNT { -// select! { -// recv(r1) -> _ => hits[0] += 1, -// recv(r2) -> _ => hits[1] += 1, -// } -// } -// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2)); -// }); - -// let mut hits = [0usize; 2]; -// for _ in 0..COUNT { -// select! { -// send(s1, ()) -> _ => hits[0] += 1, -// send(s2, ()) -> _ => hits[1] += 1, -// } -// } -// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2)); -// }) -// .unwrap(); -// } - -// #[test] -// fn fairness_duplicates() { -// const COUNT: usize = 10_000; - -// let (s, r) = bounded::<()>(0); - -// scope(|scope| { -// scope.spawn(|_| { -// let mut hits = [0usize; 5]; -// for _ in 0..COUNT { -// select! { -// recv(r) -> _ => hits[0] += 1, -// recv(r) -> _ => hits[1] += 1, -// recv(r) -> _ => hits[2] += 1, -// recv(r) -> _ => hits[3] += 1, -// recv(r) -> _ => hits[4] += 1, -// } -// } -// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2)); -// }); - -// let mut hits = [0usize; 5]; -// for _ in 0..COUNT { -// select! { -// send(s, ()) -> _ => hits[0] += 1, -// send(s, ()) -> _ => hits[1] += 1, -// send(s, ()) -> _ => hits[2] += 1, -// send(s, ()) -> _ => hits[3] += 1, -// send(s, ()) -> _ => hits[4] += 1, -// } -// } -// assert!(hits.iter().all(|x| *x >= COUNT / hits.len() / 2)); -// }) -// .unwrap(); -// } - -// #[test] -// fn recv_in_send() { -// let (s, r) = bounded(0); - -// scope(|scope| { -// scope.spawn(|_| { -// thread::sleep(ms(100)); -// r.recv() -// }); - -// scope.spawn(|_| { -// thread::sleep(ms(500)); -// s.send(()).unwrap(); -// }); - -// select! { -// send(s, r.recv().unwrap()) -> _ => {} -// } -// }) -// .unwrap(); -// } - -#[test] -fn channel_through_channel() { - const COUNT: usize = 1000; - - type T = Box<dyn Any + Send>; - - let (s, r) = bounded::<T>(0); - - scope(|scope| { - scope.spawn(move |_| { - let mut s = s; - - for _ in 0..COUNT { - let (new_s, new_r) = bounded(0); - let new_r: T = Box::new(Some(new_r)); - - s.send(new_r).unwrap(); - s = new_s; - } - }); - - scope.spawn(move |_| { - let mut r = r; - - for _ in 0..COUNT { - r = r - .recv() - .unwrap() - .downcast_mut::<Option<Receiver<T>>>() - .unwrap() - .take() - .unwrap() - } - }); - }) - .unwrap(); -} |