Skip to content

Commit c23d8e8

Browse files
committed
Set calling process directly because delta started it
This info then takes precedence over whatever start_determining_calling_process_in_thread() finds or rather doesn't find. (The simple yet generous SeqCst is used on purpose for the atomic operations.)
1 parent 45001d6 commit c23d8e8

File tree

3 files changed

+43
-3
lines changed

3 files changed

+43
-3
lines changed

src/main.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ mod subcommands;
2424

2525
mod tests;
2626

27-
use std::ffi::OsString;
27+
use std::ffi::{OsStr, OsString};
2828
use std::io::{self, BufRead, Cursor, ErrorKind, IsTerminal, Write};
2929
use std::process::{self, Command, Stdio};
3030

@@ -91,6 +91,15 @@ pub fn run_app(
9191
} else if let Call::Help(msg) = call {
9292
OutputType::oneshot_write(msg)?;
9393
return Ok(0);
94+
} else if let Call::SubCommand(_, cmd) = &call {
95+
// Set before creating the Config, which already asks for the calling process
96+
// (not required for Call::DeltaDiff)
97+
utils::process::set_calling_process(
98+
&cmd.args
99+
.iter()
100+
.map(|arg| OsStr::to_string_lossy(arg).to_string())
101+
.collect::<Vec<_>>(),
102+
);
94103
}
95104
let opt = opt.unwrap_or_else(|| delta_unreachable("Opt is set"));
96105

src/utils/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,7 @@ pub mod round_char_boundary;
99
pub mod syntect;
1010
pub mod tabs;
1111
pub mod workarounds;
12+
13+
// Use the most (even overly) strict ordering. Atomics are not used in hot loops so
14+
// a one-size-fits-all approach which is never incorrect is okay.
15+
pub const DELTA_ATOMIC_ORDERING: std::sync::atomic::Ordering = std::sync::atomic::Ordering::SeqCst;

src/utils/process.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
use std::collections::{HashMap, HashSet};
22
use std::path::Path;
3+
use std::sync::atomic::AtomicUsize;
34
use std::sync::{Arc, Condvar, Mutex, MutexGuard};
45

56
use lazy_static::lazy_static;
67
use sysinfo::{Pid, PidExt, Process, ProcessExt, ProcessRefreshKind, SystemExt};
78

9+
use crate::utils::DELTA_ATOMIC_ORDERING;
10+
811
pub type DeltaPid = u32;
912

1013
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -19,7 +22,13 @@ pub enum CallingProcess {
1922
None, // no matching process could be found
2023
Pending, // calling process is currently being determined
2124
}
22-
// TODO: Git blame is currently handled differently
25+
26+
// The information where the calling process info comes from *should* be inside
27+
// `CallingProcess`, but that is handed out (within a MutexGuard) to callers.
28+
// To keep the interface simple, store it here:
29+
static CALLER_INFO_SOURCE: AtomicUsize = AtomicUsize::new(CALLER_GUESSED);
30+
const CALLER_GUESSED: usize = 1;
31+
const CALLER_KNOWN: usize = 2;
2332

2433
impl CallingProcess {
2534
pub fn paths_in_input_are_relative_to_cwd(&self) -> bool {
@@ -47,6 +56,8 @@ lazy_static! {
4756
Arc::new((Mutex::new(CallingProcess::Pending), Condvar::new()));
4857
}
4958

59+
// delta was called by this process (or called by something which called delta and it),
60+
// try looking up this information in the process tree.
5061
pub fn start_determining_calling_process_in_thread() {
5162
// The handle is neither kept nor returned nor joined but dropped, so the main
5263
// thread can exit early if it does not need to know its parent process.
@@ -58,12 +69,28 @@ pub fn start_determining_calling_process_in_thread() {
5869
let (caller_mutex, determine_done) = &**CALLER;
5970

6071
let mut caller = caller_mutex.lock().unwrap();
61-
*caller = calling_process;
72+
73+
if CALLER_INFO_SOURCE.load(DELTA_ATOMIC_ORDERING) <= CALLER_GUESSED {
74+
*caller = calling_process;
75+
}
76+
6277
determine_done.notify_all();
6378
})
6479
.unwrap();
6580
}
6681

82+
// delta starts the process, so it is known.
83+
pub fn set_calling_process(args: &[String]) {
84+
if let ProcessArgs::Args(result) = describe_calling_process(args) {
85+
let (caller_mutex, determine_done) = &**CALLER;
86+
87+
let mut caller = caller_mutex.lock().unwrap();
88+
*caller = result;
89+
CALLER_INFO_SOURCE.store(CALLER_KNOWN, DELTA_ATOMIC_ORDERING);
90+
determine_done.notify_all();
91+
}
92+
}
93+
6794
#[cfg(not(test))]
6895
pub fn calling_process() -> MutexGuard<'static, CallingProcess> {
6996
let (caller_mutex, determine_done) = &**CALLER;

0 commit comments

Comments
 (0)