diff --git a/Cargo.lock b/Cargo.lock index f018df386..a8c3708c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -126,108 +126,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" -[[package]] -name = "async-channel" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" -dependencies = [ - "concurrent-queue", - "event-listener", - "futures-core", -] - -[[package]] -name = "async-executor" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17adb73da160dfb475c183343c8cccd80721ea5a605d3eb57125f0a7b7a92d0b" -dependencies = [ - "async-lock", - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "slab", -] - -[[package]] -name = "async-fs" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" -dependencies = [ - "async-lock", - "autocfg", - "blocking", - "futures-lite", -] - -[[package]] -name = "async-io" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c374dda1ed3e7d8f0d9ba58715f924862c63eae6849c92d3a18e7fbde9e2794" -dependencies = [ - "async-lock", - "autocfg", - "concurrent-queue", - "futures-lite", - "libc", - "log", - "parking", - "polling", - "slab", - "socket2", - "waker-fn", - "windows-sys 0.42.0", -] - -[[package]] -name = "async-lock" -version = "2.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa24f727524730b077666307f2734b4a1a1c57acb79193127dcc8914d5242dd7" -dependencies = [ - "event-listener", -] - -[[package]] -name = "async-net" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4051e67316bc7eff608fe723df5d32ed639946adcd69e07df41fd42a7b411f1f" -dependencies = [ - "async-io", - "autocfg", - "blocking", - "futures-lite", -] - -[[package]] -name = "async-process" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6381ead98388605d0d9ff86371043b5aa922a3905824244de40dc263a14fcba4" -dependencies = [ - "async-io", - "async-lock", - "autocfg", - "blocking", - "cfg-if", - "event-listener", - "futures-lite", - "libc", - "signal-hook", - "windows-sys 0.42.0", -] - -[[package]] -name = "async-task" -version = "4.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" - [[package]] name = "async-trait" version = "0.1.67" @@ -239,12 +137,6 @@ dependencies = [ "syn 2.0.3", ] -[[package]] -name = "atomic-waker" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "debc29dde2e69f9e47506b525f639ed42300fc014a3e007832592448fa8e4599" - [[package]] name = "atty" version = "0.2.14" @@ -298,20 +190,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "blocking" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c67b173a56acffd6d2326fb7ab938ba0b00a71480e14902b2591c87bc5741e8" -dependencies = [ - "async-channel", - "async-lock", - "async-task", - "atomic-waker", - "fastrand", - "futures-lite", -] - [[package]] name = "bstr" version = "0.2.17" @@ -356,6 +234,12 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + [[package]] name = "bytesize" version = "1.2.0" @@ -914,15 +798,6 @@ dependencies = [ "windows-sys 0.45.0", ] -[[package]] -name = "concurrent-queue" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c278839b831783b70278b14df4d45e1beb1aad306c07bb796637de9a0e323e8e" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "console" version = "0.15.5" @@ -1383,12 +1258,6 @@ dependencies = [ "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" @@ -1497,21 +1366,6 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89d422fa3cbe3b40dca574ab087abb5bc98258ea57eea3fd6f1fa7162c778b91" -[[package]] -name = "futures-lite" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] - [[package]] name = "futures-macro" version = "0.3.27" @@ -2795,12 +2649,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" -[[package]] -name = "parking" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" - [[package]] name = "parking_lot" version = "0.11.2" @@ -2927,22 +2775,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "polling" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e1f879b2998099c2d69ab9605d145d5b661195627eccc680002c4918a7fb6fa" -dependencies = [ - "autocfg", - "bitflags 1.3.2", - "cfg-if", - "concurrent-queue", - "libc", - "log", - "pin-project-lite", - "windows-sys 0.45.0", -] - [[package]] name = "portable-atomic" version = "0.3.19" @@ -3267,12 +3099,11 @@ dependencies = [ "serde_json", "serde_test", "similar-asserts", - "smol", - "smol-potat", "smol_str", "snapbox", "test-case", "thiserror", + "tokio", "toml 0.7.3", "toml_edit", "tracing", @@ -3455,44 +3286,6 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" -[[package]] -name = "smol" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13f2b548cd8447f8de0fdf1c592929f70f4fc7039a05e47404b0d096ec6987a1" -dependencies = [ - "async-channel", - "async-executor", - "async-fs", - "async-io", - "async-lock", - "async-net", - "async-process", - "blocking", - "futures-lite", -] - -[[package]] -name = "smol-potat" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "894ffa61af5c0fab697c8c29b1ab10cb6ec4978a1ccac4a81b5b312df1ffd88e" -dependencies = [ - "async-io", - "smol-potat-macro", -] - -[[package]] -name = "smol-potat-macro" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b7cd8129a18069385b4eadaa81182b1451fab312ad6f58d1d99253082bf3932" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "smol_str" version = "0.1.24" @@ -3533,16 +3326,6 @@ dependencies = [ "anstream", ] -[[package]] -name = "socket2" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "sprs" version = "0.7.1" @@ -3769,6 +3552,32 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tokio" +version = "1.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64" +dependencies = [ + "autocfg", + "bytes", + "memchr", + "num_cpus", + "pin-project-lite", + "tokio-macros", + "windows-sys 0.45.0", +] + +[[package]] +name = "tokio-macros" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "toml" version = "0.4.10" @@ -3992,12 +3801,6 @@ dependencies = [ "libc", ] -[[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" diff --git a/Cargo.toml b/Cargo.toml index badd93ae0..67a48ea47 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,13 +55,12 @@ serde = { version = "1.0.158", features = ["serde_derive"] } serde_json = "1.0.94" serde_test = "1.0.147" similar-asserts = { version = "1.4.2", features = ["serde"] } -smol = "1.3.0" -smol-potat = "1.1.2" smol_str = { version = "0.1.23", features = ["serde"] } snapbox = { version = "0.4.10", features = ["cmd", "path"] } tempfile = "3.4.0" test-case = "3.0.0" thiserror = "1.0.39" +tokio = { version = "1.26.0", features = ["macros", "io-util", "rt", "rt-multi-thread", "sync"] } toml = "0.7.1" toml_edit = { version = "0.19.7", features = ["serde"] } tracing = "0.1.37" diff --git a/scarb/Cargo.toml b/scarb/Cargo.toml index baf4fbfd3..4716ec4ba 100644 --- a/scarb/Cargo.toml +++ b/scarb/Cargo.toml @@ -46,7 +46,7 @@ scarb-metadata = { version = "1.0.1", path = "../scarb-metadata", default-featur semver.workspace = true serde.workspace = true serde_json.workspace = true -smol.workspace = true +tokio.workspace = true smol_str.workspace = true thiserror.workspace = true toml.workspace = true @@ -68,7 +68,6 @@ ntest.workspace = true predicates.workspace = true serde_test.workspace = true similar-asserts.workspace = true -smol-potat.workspace = true snapbox.workspace = true test-case.workspace = true diff --git a/scarb/src/core/config.rs b/scarb/src/core/config.rs index 9d37487cb..f32bc75d1 100644 --- a/scarb/src/core/config.rs +++ b/scarb/src/core/config.rs @@ -7,6 +7,7 @@ use std::{env, mem}; use anyhow::{anyhow, Context, Result}; use camino::{Utf8Path, Utf8PathBuf}; use once_cell::sync::OnceCell; +use tokio::runtime::{Builder, Handle, Runtime}; use tracing::trace; use which::which_in; @@ -32,6 +33,8 @@ pub struct Config { log_filter_directive: OsString, offline: bool, compilers: CompilerRepository, + tokio_runtime: OnceCell, + tokio_handle: OnceCell, } impl Config { @@ -65,6 +68,10 @@ impl Config { })); let compilers = b.compilers.unwrap_or_else(CompilerRepository::std); + let tokio_handle: OnceCell = OnceCell::new(); + if let Some(handle) = b.tokio_handle { + tokio_handle.set(handle).unwrap(); + } Ok(Self { manifest_path: b.manifest_path, @@ -77,6 +84,8 @@ impl Config { log_filter_directive: b.log_filter_directive.unwrap_or_default(), offline: b.offline, compilers, + tokio_runtime: OnceCell::new(), + tokio_handle, }) } @@ -171,6 +180,23 @@ impl Config { not_static_al } + pub fn tokio_handle(&self) -> &Handle { + self.tokio_handle.get_or_init(|| { + // No tokio runtime handle stored yet. + if let Ok(handle) = Handle::try_current() { + // Check if we're already in a tokio runtime. + handle + } else { + // Otherwise, start a new one. + let runtime = self + .tokio_runtime + .get_or_init(|| Builder::new_multi_thread().enable_all().build().unwrap()); + + runtime.handle().clone() + } + }) + } + /// States whether the _Offline Mode_ is turned on. /// /// For checking whether Scarb can communicate with the network, prefer to use @@ -202,6 +228,7 @@ pub struct ConfigBuilder { offline: bool, log_filter_directive: Option, compilers: Option, + tokio_handle: Option, } impl ConfigBuilder { @@ -217,6 +244,7 @@ impl ConfigBuilder { offline: false, log_filter_directive: None, compilers: None, + tokio_handle: None, } } @@ -280,4 +308,9 @@ impl ConfigBuilder { self.compilers = Some(compilers); self } + + pub fn tokio_handle(mut self, tokio_handle: Handle) -> Self { + self.tokio_handle = Some(tokio_handle); + self + } } diff --git a/scarb/src/core/registry/source_map.rs b/scarb/src/core/registry/source_map.rs index 541111ef5..cad81ea15 100644 --- a/scarb/src/core/registry/source_map.rs +++ b/scarb/src/core/registry/source_map.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use anyhow::Result; use async_trait::async_trait; use itertools::Itertools; -use smol::lock::RwLock; +use tokio::sync::RwLock; use tracing::trace; use crate::core::registry::Registry; diff --git a/scarb/src/flock.rs b/scarb/src/flock.rs index 3f4d85001..3e393065d 100644 --- a/scarb/src/flock.rs +++ b/scarb/src/flock.rs @@ -6,10 +6,9 @@ use std::{fmt, io}; use anyhow::{Context, Result}; use camino::{Utf8Path, Utf8PathBuf}; use fs4::{lock_contended_error, FileExt}; -use smol::lock::Mutex; +use tokio::sync::Mutex; use crate::core::Config; -use crate::internal::asyncx::AwaitSync; use crate::internal::fsx; use crate::internal::lazy_directory_creator::LazyDirectoryCreator; use crate::ui::Status; @@ -79,16 +78,11 @@ pub struct AdvisoryLock<'f> { pub struct AdvisoryLockGuard(Arc); impl<'f> AdvisoryLock<'f> { - /// Acquires this advisory lock. + /// Acquires this advisory lock in an async manner. /// /// This lock is global per-process and can be acquired recursively. /// An RAII structure is returned to release the lock, and if this process abnormally /// terminates the lock is also released. - pub fn acquire(&self) -> Result { - self.acquire_async().await_sync() - } - - /// Async version of [`Self::acquire`]. pub async fn acquire_async(&self) -> Result { let mut slot = self.file_lock.lock().await; diff --git a/scarb/src/internal/async_cache.rs b/scarb/src/internal/async_cache.rs index 6dd299150..28597c719 100644 --- a/scarb/src/internal/async_cache.rs +++ b/scarb/src/internal/async_cache.rs @@ -4,7 +4,7 @@ use std::hash::Hash; use anyhow::Result; use futures::future::{LocalBoxFuture, Shared}; use futures::prelude::*; -use smol::lock::RwLock; +use tokio::sync::RwLock; use crate::internal::cloneable_error::CloneableResult; @@ -58,7 +58,7 @@ mod tests { use super::AsyncCache; - #[smol_potat::test] + #[tokio::test] async fn load() { let cache = AsyncCache::new((), |key: usize, _ctx: ()| { static COUNTER: AtomicU8 = AtomicU8::new(0); @@ -71,7 +71,7 @@ mod tests { assert_eq!(cache.load(2).await.unwrap(), (2, 1)); } - #[smol_potat::test] + #[tokio::test] async fn load_err() { let cache = AsyncCache::new((), |key: usize, _ctx: ()| { static COUNTER: AtomicU8 = AtomicU8::new(0); diff --git a/scarb/src/internal/asyncx.rs b/scarb/src/internal/asyncx.rs deleted file mode 100644 index 7ce94f470..000000000 --- a/scarb/src/internal/asyncx.rs +++ /dev/null @@ -1,17 +0,0 @@ -use std::future::IntoFuture; - -pub trait AwaitSync { - /// The output that the future will produce on completion. - type Output; - - /// Synchronously await a future by starting a small one-off runtime internally. - fn await_sync(self) -> Self::Output; -} - -impl AwaitSync for F { - type Output = F::Output; - - fn await_sync(self) -> Self::Output { - smol::block_on(self.into_future()) - } -} diff --git a/scarb/src/internal/mod.rs b/scarb/src/internal/mod.rs index 87d3f42d8..8c7242345 100644 --- a/scarb/src/internal/mod.rs +++ b/scarb/src/internal/mod.rs @@ -1,5 +1,4 @@ pub mod async_cache; -pub mod asyncx; pub mod cloneable_error; pub mod fsx; pub mod lazy_directory_creator; diff --git a/scarb/src/ops/resolve.rs b/scarb/src/ops/resolve.rs index 36bc62bbc..225f1ae1e 100644 --- a/scarb/src/ops/resolve.rs +++ b/scarb/src/ops/resolve.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use anyhow::Result; +use futures::TryFutureExt; use itertools::Itertools; use crate::compiler::{CompilationUnit, CompilationUnitComponent, Profile}; @@ -11,7 +12,6 @@ use crate::core::registry::Registry; use crate::core::resolver::Resolve; use crate::core::workspace::Workspace; use crate::core::Target; -use crate::internal::asyncx::AwaitSync; use crate::resolver; pub struct WorkspaceResolve { @@ -38,22 +38,25 @@ impl WorkspaceResolve { fields(root = ws.root().to_string()) )] pub fn resolve_workspace(ws: &Workspace<'_>) -> Result { - async { - let source_map = SourceMap::preloaded(ws.members(), ws.config()); - let mut registry_cache = RegistryCache::new(source_map); + ws.config().tokio_handle().block_on( + async { + let source_map = SourceMap::preloaded(ws.members(), ws.config()); + let mut registry_cache = RegistryCache::new(source_map); - let members_summaries = ws - .members() - .map(|pkg| pkg.manifest.summary.clone()) - .collect::>(); + let members_summaries = ws + .members() + .map(|pkg| pkg.manifest.summary.clone()) + .collect::>(); - let resolve = resolver::resolve(&members_summaries, &mut registry_cache).await?; + let resolve = resolver::resolve(&members_summaries, &mut registry_cache).await?; - let packages = collect_packages_from_resolve_graph(&resolve, &mut registry_cache).await?; + let packages = + collect_packages_from_resolve_graph(&resolve, &mut registry_cache).await?; - Ok(WorkspaceResolve { resolve, packages }) - } - .await_sync() + Ok(WorkspaceResolve { resolve, packages }) + } + .into_future(), + ) } #[tracing::instrument(skip_all, level = "debug")] diff --git a/scarb/src/resolver/mod.rs b/scarb/src/resolver/mod.rs index 1d21440a2..c0f55d222 100644 --- a/scarb/src/resolver/mod.rs +++ b/scarb/src/resolver/mod.rs @@ -122,17 +122,18 @@ mod tests { use itertools::Itertools; use semver::Version; use similar_asserts::assert_serde_eq; + use tokio::runtime::Builder; use crate::core::package::PackageName; use crate::core::registry::mock::{deps, pkgs, registry, MockRegistry}; use crate::core::{ManifestDependency, PackageId, SourceId}; - use crate::internal::asyncx::AwaitSync; fn check( mut registry: MockRegistry, roots: &[&[ManifestDependency]], expected: Result<&[PackageId], &str>, ) { + let runtime = Builder::new_multi_thread().build().unwrap(); let root_names = (1..).map(|n| PackageName::new(format!("ROOT_{n}"))); let summaries = roots @@ -150,7 +151,7 @@ mod tests { }) .collect_vec(); - let resolve = super::resolve(&summaries, &mut registry).await_sync(); + let resolve = runtime.block_on(super::resolve(&summaries, &mut registry)); let resolve = resolve .map(|r| { diff --git a/scarb/src/sources/git/mod.rs b/scarb/src/sources/git/mod.rs index a8872b0f9..39b45a207 100644 --- a/scarb/src/sources/git/mod.rs +++ b/scarb/src/sources/git/mod.rs @@ -2,8 +2,8 @@ use std::{fmt, mem}; use anyhow::{Context, Result}; use async_trait::async_trait; -use smol::lock::OnceCell; -use smol::unblock; +use tokio::sync::OnceCell; +use tokio::task::spawn_blocking; use url::Url; use canonical_url::CanonicalUrl; @@ -81,8 +81,10 @@ impl<'c> GitSource<'c> { // but `smol::unblock` lifetime bounds force us to think so. let config: &'static Config = unsafe { mem::transmute(self.config) }; - return unblock(move || inner(source_id, remote, requested_reference, locked_rev, config)) - .await; + return spawn_blocking(move || { + inner(source_id, remote, requested_reference, locked_rev, config) + }) + .await?; fn inner( source_id: SourceId, diff --git a/scarb/src/sources/path.rs b/scarb/src/sources/path.rs index e7b0505dd..a0934f3ba 100644 --- a/scarb/src/sources/path.rs +++ b/scarb/src/sources/path.rs @@ -4,7 +4,7 @@ use std::ops::Deref; use anyhow::{anyhow, Result}; use async_trait::async_trait; use camino::Utf8Path; -use smol::lock::OnceCell; +use tokio::sync::OnceCell; use crate::core::config::Config; use crate::core::manifest::{ManifestDependency, Summary}; diff --git a/scarb/src/sources/standard_lib.rs b/scarb/src/sources/standard_lib.rs index ad57d5b74..2eca18138 100644 --- a/scarb/src/sources/standard_lib.rs +++ b/scarb/src/sources/standard_lib.rs @@ -3,7 +3,7 @@ use std::fmt; use anyhow::{Context, Result}; use async_trait::async_trait; use include_dir::{include_dir, Dir}; -use smol::lock::OnceCell; +use tokio::sync::OnceCell; use tracing::trace; use crate::core::config::Config; diff --git a/scarb/tests/e2e/flock.rs b/scarb/tests/e2e/flock.rs index 1c4cb1684..aeb28254e 100644 --- a/scarb/tests/e2e/flock.rs +++ b/scarb/tests/e2e/flock.rs @@ -74,9 +74,9 @@ fn locking_build_artifacts() { }); } -#[test] +#[tokio::test(flavor = "multi_thread")] #[timeout(60_000)] -fn locking_package_cache() { +async fn locking_package_cache() { let t = assert_fs::TempDir::new().unwrap(); ProjectBuilder::start() .name("hello") @@ -86,49 +86,48 @@ fn locking_package_cache() { let manifest = t.child("Scarb.toml"); let config = Scarb::test_config(manifest); - thread::scope(|s| { - let lock = config.package_cache_lock().acquire(); - let barrier = Arc::new(Barrier::new(2)); - - s.spawn({ - let barrier = barrier.clone(); - move || { - barrier.wait(); - drop(lock); - } - }); + let lock = config.package_cache_lock().acquire_async().await; + let barrier = Arc::new(Barrier::new(2)); - let mut proc = Scarb::from_config(&config) - .std() - .arg("build") - .current_dir(&t) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .spawn() - .unwrap(); + tokio::spawn({ + let barrier = barrier.clone(); - let mut stdout_acc = Vec::::new(); - let stdout = proc.stdout.take().unwrap(); - let stdout = TeeReader::new(stdout, &mut stdout_acc); - let stdout = BufReader::new(stdout); - for line in stdout.lines() { - let line = line.unwrap(); + async move { + barrier.wait(); + drop(lock); + } + }); - if line.contains("waiting for file lock on package cache") { - barrier.wait(); - } + let mut proc = Scarb::from_config(&config) + .std() + .arg("build") + .current_dir(&t) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .unwrap(); + + let mut stdout_acc = Vec::::new(); + let stdout = proc.stdout.take().unwrap(); + let stdout = TeeReader::new(stdout, &mut stdout_acc); + let stdout = BufReader::new(stdout); + for line in stdout.lines() { + let line = line.unwrap(); + + if line.contains("waiting for file lock on package cache") { + barrier.wait(); } + } - let ecode = proc.wait().unwrap(); - assert!(ecode.success()); + let ecode = proc.wait().unwrap(); + assert!(ecode.success()); - snapbox::assert_matches( - indoc! {r#" + snapbox::assert_matches( + indoc! {r#" [..] Blocking waiting for file lock on package cache [..] Compiling hello v0.1.0 ([..]) [..] Finished release target(s) in [..] "#}, - stdout_acc, - ); - }); + stdout_acc, + ); }