video: Fix race condition if multiple video backends are downloading OpenH264 at the same time

Co-authored-by: TÖRÖK Attila <torokati44@gmail.com>
This commit is contained in:
Nathan Adams 2024-08-07 21:22:12 +02:00 committed by Kamil Jarosz
parent 9b5e33ab7d
commit 23d4a61fbd
3 changed files with 13 additions and 7 deletions

1
Cargo.lock generated
View File

@ -4565,6 +4565,7 @@ dependencies = [
"ruffle_video_software",
"slotmap",
"swf",
"tempfile",
"tracing",
]

View File

@ -21,6 +21,7 @@ md-5 = "0.10.6"
reqwest = { version = "0.12.5", default-features = false, features = ["blocking"] }
hex = "0.4.3"
bzip2 = { version = "0.4.4", features = ["static"] }
tempfile = "3.11.0"
[package.metadata.cargo-machete]
ignored = [

View File

@ -85,20 +85,24 @@ impl ExternalVideoBackend {
let (filename, md5sum) = Self::get_openh264_data()?;
let filepath = std::env::current_exe()?
let current_exe = std::env::current_exe()?;
let directory = current_exe
.parent()
.ok_or("Could not determine Ruffle location.")?
.join(filename);
.ok_or("Could not determine Ruffle location.")?;
let filepath = directory.join(filename);
// If the binary doesn't exist in the expected location, download it.
if !filepath.is_file() {
let url = format!("{}{}{}", URL_BASE, filename, URL_SUFFIX);
let response = reqwest::blocking::get(url)?;
let bytes = response.bytes()?;
let mut bzip2_reader = BzDecoder::new(bytes.as_ref());
let mut bzip2_reader = BzDecoder::new(response);
let mut file = File::create(filepath.clone())?;
copy(&mut bzip2_reader, &mut file)?;
let mut tempfile = tempfile::NamedTempFile::with_prefix_in(filename, directory)?;
copy(&mut bzip2_reader, &mut tempfile)?;
// Let's assume that if this fails, it's because another process has already put it there
// and loaded it, therefore it can't be overwritten (on Windows at least), but in the end,
// all's fine - the MD5 hash will still be checked before attempting to load the library.
let _ = tempfile.persist(&filepath);
}
// Regardless of whether the library was already there, or we just downloaded it, let's check the MD5 hash.