fix(solc): take installer lock before installing (#801)

This commit is contained in:
Matthias Seitz 2022-01-17 14:51:15 +01:00 committed by GitHub
parent afcba9567f
commit e0ee033283
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 3 deletions

View File

@ -47,6 +47,19 @@ use std::sync::Mutex;
#[allow(unused)] #[allow(unused)]
static LOCK: Lazy<Mutex<()>> = Lazy::new(|| Mutex::new(())); static LOCK: Lazy<Mutex<()>> = Lazy::new(|| Mutex::new(()));
/// take the lock in tests, we use this to enforce that
/// a test does not run while a compiler version is being installed
///
/// This ensures that only one thread installs a missing `solc` exe.
/// Instead of taking this lock in `Solc::blocking_install`, the lock should be taken before
/// installation is detected.
#[cfg(any(test, feature = "tests"))]
#[allow(unused)]
pub(crate) fn take_solc_installer_lock() -> std::sync::LockResult<std::sync::MutexGuard<'static, ()>>
{
LOCK.lock()
}
#[cfg(all(feature = "svm", feature = "async"))] #[cfg(all(feature = "svm", feature = "async"))]
/// A list of upstream Solc releases, used to check which version /// A list of upstream Solc releases, used to check which version
/// we should download. /// we should download.
@ -289,9 +302,7 @@ impl Solc {
#[cfg(all(feature = "svm", feature = "async"))] #[cfg(all(feature = "svm", feature = "async"))]
pub fn ensure_installed(sol_version: &VersionReq) -> Result<Version> { pub fn ensure_installed(sol_version: &VersionReq) -> Result<Version> {
#[cfg(any(test, feature = "tests"))] #[cfg(any(test, feature = "tests"))]
// take the lock in tests, we use this to enforce that let _lock = take_solc_installer_lock();
// a test does not run while a compiler version is being installed
let _lock = LOCK.lock();
// load the local / remote versions // load the local / remote versions
let versions = utils::installed_versions(svm::SVM_HOME.as_path()).unwrap_or_default(); let versions = utils::installed_versions(svm::SVM_HOME.as_path()).unwrap_or_default();

View File

@ -385,6 +385,10 @@ impl VersionedSources {
) -> Result<std::collections::BTreeMap<Solc, Sources>> { ) -> Result<std::collections::BTreeMap<Solc, Sources>> {
use crate::SolcError; use crate::SolcError;
// we take the installer lock here to ensure installation checking is done in sync
#[cfg(any(test, feature = "tests"))]
let _lock = crate::compile::take_solc_installer_lock();
let mut sources_by_version = std::collections::BTreeMap::new(); let mut sources_by_version = std::collections::BTreeMap::new();
for (version, sources) in self.inner { for (version, sources) in self.inner {
if !version.is_installed() { if !version.is_installed() {