media: isolate mjpeg spool temp files
This commit is contained in:
parent
ed3ed1a165
commit
602974b04e
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -1652,7 +1652,7 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
|
||||
|
||||
[[package]]
|
||||
name = "lesavka_client"
|
||||
version = "0.22.25"
|
||||
version = "0.22.26"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-stream",
|
||||
@ -1686,7 +1686,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "lesavka_common"
|
||||
version = "0.22.25"
|
||||
version = "0.22.26"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64",
|
||||
@ -1698,7 +1698,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "lesavka_server"
|
||||
version = "0.22.25"
|
||||
version = "0.22.26"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64",
|
||||
|
||||
@ -4,7 +4,7 @@ path = "src/main.rs"
|
||||
|
||||
[package]
|
||||
name = "lesavka_client"
|
||||
version = "0.22.25"
|
||||
version = "0.22.26"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "lesavka_common"
|
||||
version = "0.22.25"
|
||||
version = "0.22.26"
|
||||
edition = "2024"
|
||||
build = "build.rs"
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ bench = false
|
||||
|
||||
[package]
|
||||
name = "lesavka_server"
|
||||
version = "0.22.25"
|
||||
version = "0.22.26"
|
||||
edition = "2024"
|
||||
autobins = false
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ use gstreamer as gst;
|
||||
use gstreamer_app as gst_app;
|
||||
|
||||
static SPOOL_SEQUENCE: AtomicU64 = AtomicU64::new(1);
|
||||
static SPOOL_TEMP_SEQUENCE: AtomicU64 = AtomicU64::new(1);
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(super) struct MjpegSpoolTiming {
|
||||
@ -226,7 +227,11 @@ pub(super) fn spool_mjpeg_frame_with_timing(
|
||||
if let Some(parent) = path.parent() {
|
||||
fs::create_dir_all(parent)?;
|
||||
}
|
||||
let tmp = path.with_extension(format!("mjpg.{}.tmp", std::process::id()));
|
||||
let tmp = path.with_extension(format!(
|
||||
"mjpg.{}.{}.tmp",
|
||||
std::process::id(),
|
||||
SPOOL_TEMP_SEQUENCE.fetch_add(1, Ordering::Relaxed)
|
||||
));
|
||||
fs::write(&tmp, data)?;
|
||||
fs::rename(&tmp, path)?;
|
||||
|
||||
|
||||
@ -101,3 +101,17 @@ fn mjpeg_passthrough_spool_keeps_decode_timing_null() {
|
||||
assert!(sidecar_text.contains("\"source_pts_us\":55000"));
|
||||
assert!(sidecar_text.contains("\"decoded_pts_us\":null"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mjpeg_spool_uses_unique_temporary_paths_per_publish() {
|
||||
let source = include_str!(concat!(
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
"/server/src/video_sinks/mjpeg_spool.rs"
|
||||
));
|
||||
|
||||
assert!(source.contains("static SPOOL_TEMP_SEQUENCE"));
|
||||
assert!(
|
||||
source.contains("SPOOL_TEMP_SEQUENCE.fetch_add(1, Ordering::Relaxed)"),
|
||||
"shared MJPEG spool writers must not reuse a single process-wide temp path"
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user