cosmic_files/operation/
notifiers.rs

1// Copyright 2026 System76 <info@system76.com>
2// SPDX-License-Identifier: GPL-3.0-only
3
4use std::path::{Path, PathBuf};
5use std::sync::{Arc, LazyLock, Mutex};
6use tokio::sync::Notify;
7
8/// Monitor files which are being written to.
9pub struct FileWritingNotifier {
10    data: Vec<PathBuf>,
11    notify: Arc<Notify>,
12}
13
14static ACTIVELY_WRITING: LazyLock<Mutex<FileWritingNotifier>> = LazyLock::new(|| {
15    Mutex::new(FileWritingNotifier {
16        data: Vec::new(),
17        notify: Arc::new(Notify::new()),
18    })
19});
20
21/// Append path that is being written to.
22pub fn actively_writing_add(path: PathBuf) {
23    ACTIVELY_WRITING.lock().unwrap().data.push(path);
24}
25
26/// Remove path to file that has finished writing and notify waiters.
27pub fn actively_writing_remove(path: &Path) {
28    let mut guard = ACTIVELY_WRITING.lock().unwrap();
29    guard.data.retain(|p| p != path);
30    guard.notify.notify_waiters();
31}
32
33/// Wait until the actively-writing queue is empty or a file has been removed.
34pub async fn actively_writing_tick() {
35    let notify = (|| {
36        let guard = ACTIVELY_WRITING.lock().unwrap();
37
38        if !guard.data.is_empty() {
39            return Some(guard.notify.clone());
40        }
41
42        None
43    })();
44
45    if let Some(notify) = notify {
46        notify.notified().await
47    }
48}
49
50/// Check if a file is being written to. Avoid thumbnail generation until after it is finished.
51pub fn is_actively_writing_to(path: &Path) -> bool {
52    ACTIVELY_WRITING
53        .lock()
54        .unwrap()
55        .data
56        .iter()
57        .any(|p| p == path)
58}