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 use self::controller::{Controller, ControllerState};
|
||||||
pub mod controller;
|
pub mod controller;
|
||||||
|
|
||||||
|
pub use notifiers::*;
|
||||||
|
mod notifiers;
|
||||||
|
|
||||||
pub use self::reader::OpReader;
|
pub use self::reader::OpReader;
|
||||||
pub mod reader;
|
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 {
|
match self.kind {
|
||||||
OpKind::Copy => {
|
OpKind::Copy => {
|
||||||
|
crate::operation::actively_writing_add(self.to.clone());
|
||||||
let result = self.copy(ctx, progress).await;
|
let result = self.copy(ctx, progress).await;
|
||||||
|
|
||||||
if result.is_err() {
|
if result.is_err() {
|
||||||
_ = compio::fs::remove_file(&self.to).await;
|
_ = compio::fs::remove_file(&self.to).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
crate::operation::actively_writing_remove(&self.to);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
OpKind::Move { cross_device_copy } => {
|
OpKind::Move { cross_device_copy } => {
|
||||||
|
|
|
||||||
|
|
@ -6771,6 +6771,10 @@ impl Tab {
|
||||||
stream::channel(
|
stream::channel(
|
||||||
1,
|
1,
|
||||||
move |mut output: futures::channel::mpsc::Sender<_>| async move {
|
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 message = {
|
||||||
let path = path.clone();
|
let path = path.clone();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue