1
1
use std:: collections:: { HashMap , HashSet } ;
2
2
use std:: path:: Path ;
3
+ use std:: sync:: atomic:: AtomicUsize ;
3
4
use std:: sync:: { Arc , Condvar , Mutex , MutexGuard } ;
4
5
5
6
use lazy_static:: lazy_static;
6
7
use sysinfo:: { Pid , PidExt , Process , ProcessExt , ProcessRefreshKind , SystemExt } ;
7
8
9
+ use crate :: utils:: DELTA_ATOMIC_ORDERING ;
10
+
8
11
pub type DeltaPid = u32 ;
9
12
10
13
#[ derive( Clone , Debug , PartialEq , Eq ) ]
@@ -19,7 +22,13 @@ pub enum CallingProcess {
19
22
None , // no matching process could be found
20
23
Pending , // calling process is currently being determined
21
24
}
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 ;
23
32
24
33
impl CallingProcess {
25
34
pub fn paths_in_input_are_relative_to_cwd ( & self ) -> bool {
@@ -47,6 +56,8 @@ lazy_static! {
47
56
Arc :: new( ( Mutex :: new( CallingProcess :: Pending ) , Condvar :: new( ) ) ) ;
48
57
}
49
58
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.
50
61
pub fn start_determining_calling_process_in_thread ( ) {
51
62
// The handle is neither kept nor returned nor joined but dropped, so the main
52
63
// 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() {
58
69
let ( caller_mutex, determine_done) = & * * CALLER ;
59
70
60
71
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
+
62
77
determine_done. notify_all ( ) ;
63
78
} )
64
79
. unwrap ( ) ;
65
80
}
66
81
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
+
67
94
#[ cfg( not( test) ) ]
68
95
pub fn calling_process ( ) -> MutexGuard < ' static , CallingProcess > {
69
96
let ( caller_mutex, determine_done) = & * * CALLER ;
0 commit comments