fix: do not generate thumbnail if file is being written
This commit is contained in:
parent
0bd20e57e7
commit
15e40461e5
4 changed files with 67 additions and 0 deletions
|
|
@ -22,6 +22,9 @@ use zip::AesMode::Aes256;
|
|||
pub use self::controller::{Controller, ControllerState};
|
||||
pub mod controller;
|
||||
|
||||
pub use notifiers::*;
|
||||
mod notifiers;
|
||||
|
||||
pub use self::reader::OpReader;
|
||||
pub mod reader;
|
||||
|
||||
|
|
|
|||
58
src/operation/notifiers.rs
Normal file
58
src/operation/notifiers.rs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
// Copyright 2026 System76 <info@system76.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::{Arc, LazyLock, Mutex};
|
||||
use tokio::sync::Notify;
|
||||
|
||||
/// Monitor files which are being written to.
|
||||
pub struct FileWritingNotifier {
|
||||
data: Vec<PathBuf>,
|
||||
notify: Arc<Notify>,
|
||||
}
|
||||
|
||||
static ACTIVELY_WRITING: LazyLock<Mutex<FileWritingNotifier>> = LazyLock::new(|| {
|
||||
Mutex::new(FileWritingNotifier {
|
||||
data: Vec::new(),
|
||||
notify: Arc::new(Notify::new()),
|
||||
})
|
||||
});
|
||||
|
||||
/// Append path that is being written to.
|
||||
pub fn actively_writing_add(path: PathBuf) {
|
||||
ACTIVELY_WRITING.lock().unwrap().data.push(path);
|
||||
}
|
||||
|
||||
/// Remove path to file that has finished writing and notify waiters.
|
||||
pub fn actively_writing_remove(path: &Path) {
|
||||
let mut guard = ACTIVELY_WRITING.lock().unwrap();
|
||||
guard.data.retain(|p| p != path);
|
||||
guard.notify.notify_waiters();
|
||||
}
|
||||
|
||||
/// Wait until the actively-writing queue is empty or a file has been removed.
|
||||
pub async fn actively_writing_tick() {
|
||||
let notify = (|| {
|
||||
let guard = ACTIVELY_WRITING.lock().unwrap();
|
||||
|
||||
if !guard.data.is_empty() {
|
||||
return Some(guard.notify.clone());
|
||||
}
|
||||
|
||||
None
|
||||
})();
|
||||
|
||||
if let Some(notify) = notify {
|
||||
notify.notified().await
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if a file is being written to. Avoid thumbnail generation until after it is finished.
|
||||
pub fn is_actively_writing_to(path: &Path) -> bool {
|
||||
ACTIVELY_WRITING
|
||||
.lock()
|
||||
.unwrap()
|
||||
.data
|
||||
.iter()
|
||||
.any(|p| p == path)
|
||||
}
|
||||
|
|
@ -334,12 +334,14 @@ impl Op {
|
|||
}
|
||||
match self.kind {
|
||||
OpKind::Copy => {
|
||||
crate::operation::actively_writing_add(self.to.clone());
|
||||
let result = self.copy(ctx, progress).await;
|
||||
|
||||
if result.is_err() {
|
||||
_ = compio::fs::remove_file(&self.to).await;
|
||||
}
|
||||
|
||||
crate::operation::actively_writing_remove(&self.to);
|
||||
return result;
|
||||
}
|
||||
OpKind::Move { cross_device_copy } => {
|
||||
|
|
|
|||
|
|
@ -6771,6 +6771,10 @@ impl Tab {
|
|||
stream::channel(
|
||||
1,
|
||||
move |mut output: futures::channel::mpsc::Sender<_>| async move {
|
||||
while crate::operation::is_actively_writing_to(&path) {
|
||||
crate::operation::actively_writing_tick().await;
|
||||
}
|
||||
|
||||
let message = {
|
||||
let path = path.clone();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue