mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-28 01:11:15 -03:00
Retry history file flock() on EINTR
When locking the uvar file, we retry whenever flock() fails with EINTR (e.g. due to ctrl-c). But not when locking the history file. This seems wrong; all other libc functions in the "history_file" code path do retry. Fix that. In future we should extract a function. Note that there are other inconsistencies; flock_uvar_file() does not shy away from remote file systems and does not respect ABANDONED_LOCKING. This means that empirically probably neither are necessary; let's make things consistent in future. See https://github.com/fish-shell/fish-shell/pull/11492#discussion_r2095096200 Might help #10300
This commit is contained in:
@@ -42,7 +42,7 @@
|
||||
};
|
||||
|
||||
use bitflags::bitflags;
|
||||
use libc::{fchown, flock, LOCK_EX, LOCK_SH, LOCK_UN};
|
||||
use libc::{fchown, flock, EINTR, LOCK_EX, LOCK_SH, LOCK_UN};
|
||||
use lru::LruCache;
|
||||
use nix::{fcntl::OFlag, sys::stat::Mode};
|
||||
use rand::Rng;
|
||||
@@ -1359,8 +1359,15 @@ unsafe fn maybe_lock_file(file: &mut File, lock_type: libc::c_int) -> bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
let start_time = SystemTime::now();
|
||||
let retval = unsafe { flock(file.as_raw_fd(), lock_type) };
|
||||
let (ok, start_time) = loop {
|
||||
let start_time = SystemTime::now();
|
||||
if unsafe { flock(file.as_raw_fd(), lock_type) } == -1 {
|
||||
if errno::errno().0 != EINTR {
|
||||
break (false, start_time);
|
||||
}
|
||||
}
|
||||
break (true, start_time);
|
||||
};
|
||||
if let Ok(duration) = start_time.elapsed() {
|
||||
if duration > Duration::from_millis(250) {
|
||||
FLOG!(
|
||||
@@ -1373,7 +1380,7 @@ unsafe fn maybe_lock_file(file: &mut File, lock_type: libc::c_int) -> bool {
|
||||
ABANDONED_LOCKING.store(true);
|
||||
}
|
||||
}
|
||||
retval != -1
|
||||
ok
|
||||
}
|
||||
|
||||
/// Unlock a history file.
|
||||
|
||||
Reference in New Issue
Block a user