1
1
use std:: collections:: { HashMap , HashSet } ;
2
2
use std:: path:: Path ;
3
+ use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
3
4
use std:: sync:: { Arc , Condvar , Mutex , MutexGuard } ;
4
5
5
6
use lazy_static:: lazy_static;
@@ -19,7 +20,6 @@ pub enum CallingProcess {
19
20
None , // no matching process could be found
20
21
Pending , // calling process is currently being determined
21
22
}
22
- // TODO: Git blame is currently handled differently
23
23
24
24
impl CallingProcess {
25
25
pub fn paths_in_input_are_relative_to_cwd ( & self ) -> bool {
@@ -47,6 +47,15 @@ lazy_static! {
47
47
Arc :: new( ( Mutex :: new( CallingProcess :: Pending ) , Condvar :: new( ) ) ) ;
48
48
}
49
49
50
+ // The information where the calling process info comes from *should* be inside
51
+ // `CallingProcess`, but that is handed out (within a MutexGuard) to callers.
52
+ // To keep the interface simple, store the info here:
53
+ static CALLER_INFO_SOURCE : AtomicUsize = AtomicUsize :: new ( CALLER_GUESSED ) ;
54
+ const CALLER_GUESSED : usize = 1 ;
55
+ const CALLER_KNOWN : usize = 2 ;
56
+
57
+ // delta was called by this process (or called by something which called delta and it),
58
+ // try looking up this information in the process tree.
50
59
pub fn start_determining_calling_process_in_thread ( ) {
51
60
// The handle is neither kept nor returned nor joined but dropped, so the main
52
61
// thread can exit early if it does not need to know its parent process.
@@ -58,12 +67,28 @@ pub fn start_determining_calling_process_in_thread() {
58
67
let ( caller_mutex, determine_done) = & * * CALLER ;
59
68
60
69
let mut caller = caller_mutex. lock ( ) . unwrap ( ) ;
61
- * caller = calling_process;
70
+
71
+ if CALLER_INFO_SOURCE . load ( Ordering :: SeqCst ) <= CALLER_GUESSED {
72
+ * caller = calling_process;
73
+ }
74
+
62
75
determine_done. notify_all ( ) ;
63
76
} )
64
77
. unwrap ( ) ;
65
78
}
66
79
80
+ // delta starts the process, so it is known.
81
+ pub fn set_calling_process ( args : & [ String ] ) {
82
+ if let ProcessArgs :: Args ( result) = describe_calling_process ( args) {
83
+ let ( caller_mutex, determine_done) = & * * CALLER ;
84
+
85
+ let mut caller = caller_mutex. lock ( ) . unwrap ( ) ;
86
+ * caller = result;
87
+ CALLER_INFO_SOURCE . store ( CALLER_KNOWN , Ordering :: SeqCst ) ;
88
+ determine_done. notify_all ( ) ;
89
+ }
90
+ }
91
+
67
92
#[ cfg( not( test) ) ]
68
93
pub fn calling_process ( ) -> MutexGuard < ' static , CallingProcess > {
69
94
let ( caller_mutex, determine_done) = & * * CALLER ;
0 commit comments