mirror of
https://github.com/narrrl/proton-drive-linux.git
synced 2026-11-04 00:47:00 +01:00
Merge remote-tracking branch 'origin/main' into fix/create-landing-counted
This commit is contained in:
commit
d2b5916b99
7 files changed
+165
-21
No files matched your search
@@ -2527,14 +2527,30 @@ fn mount_once(mountpoint: Option<PathBuf>) -> Result<pdfs_fuse::MountOutcome> {
|
||||
"could not save the refreshed session tokens; the next start may need `pdfs login`"
|
||||
);
|
||||
}
|
||||
// Dropping the runtime waits for every blocking task, however long; a call
|
||||
// still stuck on Drive would hold the stop until systemd kills it (B165).
|
||||
rt.shutdown_timeout(std::time::Duration::from_secs(2));
|
||||
release_runtime(rt, matches!(result, Ok(pdfs_fuse::MountOutcome::Shutdown)));
|
||||
|
||||
let outcome = result.context("mount failed")?;
|
||||
Ok(outcome)
|
||||
}
|
||||
|
||||
/// Let go of a mount's runtime once the mount has ended.
|
||||
///
|
||||
/// On a stop the process exits right after, so the runtime is left running
|
||||
/// for it to end with. Shutting it down first broke every thread the mount
|
||||
/// does not join, such as a size lookup or a profile backup a request started
|
||||
/// during the stop: its next call to Drive panicked with "A Tokio 1.x context
|
||||
/// was found, but it is being shutdown" (`docs/BUGS.md` B276). A mount that
|
||||
/// is about to be tried again does shut it down, because a new runtime
|
||||
/// replaces it. Dropping it would wait for every blocking task, however long;
|
||||
/// a call still stuck on Drive would hold the retry (B165).
|
||||
fn release_runtime(rt: tokio::runtime::Runtime, exiting: bool) {
|
||||
if exiting {
|
||||
std::mem::forget(rt);
|
||||
} else {
|
||||
rt.shutdown_timeout(std::time::Duration::from_secs(2));
|
||||
}
|
||||
}
|
||||
|
||||
fn cmd_pin(path: PathBuf) -> Result<()> {
|
||||
match control_request(CtlRequest::Pin {
|
||||
path: path_arg(&path)?,
|
||||
@@ -4146,6 +4162,47 @@ fn control_request(req: CtlRequest) -> Result<CtlResponse> {
|
||||
.with_context(|| format!("talk to mount daemon at {}", socket.display()))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod release_runtime_tests {
|
||||
use super::*;
|
||||
use std::time::Duration;
|
||||
|
||||
/// A thread the mount never joined still reaches Drive after a stop. It
|
||||
/// used to panic on its first timer once the runtime was shut down.
|
||||
#[test]
|
||||
fn a_thread_left_running_at_a_stop_can_still_use_the_runtime() {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let handle = rt.handle().clone();
|
||||
let (released_tx, released_rx) = std::sync::mpsc::channel();
|
||||
let straggler = std::thread::spawn(move || {
|
||||
released_rx.recv().unwrap();
|
||||
handle.block_on(async {
|
||||
tokio::time::sleep(Duration::from_millis(1)).await;
|
||||
7
|
||||
})
|
||||
});
|
||||
release_runtime(rt, true);
|
||||
released_tx.send(()).unwrap();
|
||||
assert_eq!(straggler.join().expect("the thread must not panic"), 7);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_mount_tried_again_shuts_its_runtime_down() {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let (done_tx, done_rx) = std::sync::mpsc::channel::<()>();
|
||||
rt.spawn(async move {
|
||||
let _done = done_tx;
|
||||
std::future::pending::<()>().await;
|
||||
});
|
||||
release_runtime(rt, false);
|
||||
// The task is dropped with the runtime, and its sender with it.
|
||||
assert_eq!(
|
||||
done_rx.recv_timeout(Duration::from_secs(5)),
|
||||
Err(std::sync::mpsc::RecvTimeoutError::Disconnected)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod pause_tests {
|
||||
use super::*;
|
||||
|
||||
@@ -1332,8 +1332,8 @@ mod tests {
|
||||
));
|
||||
let file = std::fs::File::create(&path).unwrap();
|
||||
let mut zip = zip::ZipWriter::new(file);
|
||||
let options: zip::write::FileOptions<'_, ()> =
|
||||
zip::write::FileOptions::default().compression_method(zip::CompressionMethod::Stored);
|
||||
let options = zip::write::SimpleFileOptions::default()
|
||||
.compression_method(zip::CompressionMethod::Stored);
|
||||
for (name, body) in files {
|
||||
zip.start_file(*name, options).unwrap();
|
||||
zip.write_all(body).unwrap();
|
||||
|
||||
Reference in new issue
Block a user