Retry opening proc-macro DLLs a few times on Windows.
This commit is contained in:
parent
a9985cf172
commit
227b2858da
@ -33,6 +33,7 @@ use rustc_target::spec::{PanicStrategy, TargetTriple};
|
||||
use proc_macro::bridge::client::ProcMacro;
|
||||
use std::ops::Fn;
|
||||
use std::path::Path;
|
||||
use std::time::Duration;
|
||||
use std::{cmp, env};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -689,8 +690,7 @@ impl<'a> CrateLoader<'a> {
|
||||
) -> Result<&'static [ProcMacro], CrateError> {
|
||||
// Make sure the path contains a / or the linker will search for it.
|
||||
let path = env::current_dir().unwrap().join(path);
|
||||
let lib = unsafe { libloading::Library::new(path) }
|
||||
.map_err(|err| CrateError::DlOpen(err.to_string()))?;
|
||||
let lib = load_dylib(&path, 5).map_err(|err| CrateError::DlOpen(err))?;
|
||||
|
||||
let sym_name = self.sess.generate_proc_macro_decls_symbol(stable_crate_id);
|
||||
let sym = unsafe { lib.get::<*const &[ProcMacro]>(sym_name.as_bytes()) }
|
||||
@ -1093,3 +1093,41 @@ fn alloc_error_handler_spans(sess: &Session, krate: &ast::Crate) -> Vec<Span> {
|
||||
visit::walk_crate(&mut f, krate);
|
||||
f.spans
|
||||
}
|
||||
|
||||
// On Windows the compiler would sometimes intermittently fail to open the
|
||||
// proc-macro DLL with `Error::LoadLibraryExW`. It is suspected that something in the
|
||||
// system still holds a lock on the file, so we retry a few times before calling it
|
||||
// an error.
|
||||
fn load_dylib(path: &Path, max_attempts: usize) -> Result<libloading::Library, String> {
|
||||
assert!(max_attempts > 0);
|
||||
|
||||
let mut last_error = None;
|
||||
|
||||
for attempt in 0..max_attempts {
|
||||
match unsafe { libloading::Library::new(&path) } {
|
||||
Ok(lib) => {
|
||||
if attempt > 0 {
|
||||
debug!(
|
||||
"Loaded proc-macro `{}` after {} attempts.",
|
||||
path.display(),
|
||||
attempt + 1
|
||||
);
|
||||
}
|
||||
return Ok(lib);
|
||||
}
|
||||
Err(err) => {
|
||||
// Only try to recover from this specific error.
|
||||
if !matches!(err, libloading::Error::LoadLibraryExW { .. }) {
|
||||
return Err(err.to_string());
|
||||
}
|
||||
|
||||
last_error = Some(err);
|
||||
std::thread::sleep(Duration::from_millis(100));
|
||||
debug!("Failed to load proc-macro `{}`. Retrying.", path.display());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug!("Failed to load proc-macro `{}` even after {} attempts.", path.display(), max_attempts);
|
||||
Err(format!("{} (retried {} times)", last_error.unwrap(), max_attempts))
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user