Skip to content

Commit

Permalink
Set calling process directly because delta started it
Browse files Browse the repository at this point in the history
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.)
  • Loading branch information
th1000s committed Nov 16, 2024
1 parent 0fcaf3c commit 6929280
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 3 deletions.
11 changes: 10 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ mod subcommands;

mod tests;

use std::ffi::OsString;
use std::ffi::{OsStr, OsString};
use std::io::{self, BufRead, Cursor, ErrorKind, IsTerminal, Write};
use std::process::{self, Command, Stdio};

Expand Down Expand Up @@ -91,6 +91,15 @@ pub fn run_app(
} else if let Call::Help(msg) = call {
OutputType::oneshot_write(msg)?;
return Ok(0);
} else if let Call::SubCommand(_, cmd) = &call {
// Set before creating the Config, which already asks for the calling process
// (not required for Call::DeltaDiff)
utils::process::set_calling_process(
&cmd.args
.iter()
.map(|arg| OsStr::to_string_lossy(arg).to_string())
.collect::<Vec<_>>(),
);
}
let opt = opt.expect("Opt is set");

Expand Down
29 changes: 27 additions & 2 deletions src/utils/process.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::collections::{HashMap, HashSet};
use std::path::Path;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::{Arc, Condvar, Mutex, MutexGuard};

use lazy_static::lazy_static;
Expand All @@ -19,7 +20,6 @@ pub enum CallingProcess {
None, // no matching process could be found
Pending, // calling process is currently being determined
}
// TODO: Git blame is currently handled differently

impl CallingProcess {
pub fn paths_in_input_are_relative_to_cwd(&self) -> bool {
Expand Down Expand Up @@ -47,6 +47,15 @@ lazy_static! {
Arc::new((Mutex::new(CallingProcess::Pending), Condvar::new()));
}

// The information where the calling process info comes from *should* be inside
// `CallingProcess`, but that is handed out (within a MutexGuard) to callers.
// To keep the interface simple, store it here:
static CALLER_INFO_SOURCE: AtomicUsize = AtomicUsize::new(CALLER_GUESSED);
const CALLER_GUESSED: usize = 1;
const CALLER_KNOWN: usize = 2;

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

let mut caller = caller_mutex.lock().unwrap();
*caller = calling_process;

if CALLER_INFO_SOURCE.load(Ordering::SeqCst) <= CALLER_GUESSED {
*caller = calling_process;
}

determine_done.notify_all();
})
.unwrap();
}

// delta starts the process, so it is known.
pub fn set_calling_process(args: &[String]) {
if let ProcessArgs::Args(result) = describe_calling_process(args) {
let (caller_mutex, determine_done) = &**CALLER;

let mut caller = caller_mutex.lock().unwrap();
*caller = result;
CALLER_INFO_SOURCE.store(CALLER_KNOWN, Ordering::SeqCst);
determine_done.notify_all();
}
}

#[cfg(not(test))]
pub fn calling_process() -> MutexGuard<'static, CallingProcess> {
let (caller_mutex, determine_done) = &**CALLER;
Expand Down

0 comments on commit 6929280

Please sign in to comment.