6
6
//! directory in each respective module.
7
7
8
8
use std:: env;
9
+ use std:: fs:: File ;
10
+ use std:: io:: { BufRead , BufReader } ;
9
11
10
12
use bootstrap:: { t, Build , Config , Subcommand , VERSION } ;
11
13
@@ -16,12 +18,17 @@ fn main() {
16
18
let mut build_lock;
17
19
let _build_lock_guard;
18
20
if cfg ! ( any( unix, windows) ) {
19
- build_lock = fd_lock:: RwLock :: new ( t ! ( std:: fs:: File :: create( config. out. join( "lock" ) ) ) ) ;
21
+ let path = config. out . join ( "lock" ) ;
22
+ build_lock = fd_lock:: RwLock :: new ( t ! ( std:: fs:: File :: create( & path) ) ) ;
20
23
_build_lock_guard = match build_lock. try_write ( ) {
21
24
Ok ( lock) => lock,
22
25
err => {
23
- println ! ( "warning: build directory locked, waiting for lock" ) ;
24
26
drop ( err) ;
27
+ if let Some ( pid) = get_lock_owner ( & path) {
28
+ println ! ( "warning: build directory locked by process {pid}, waiting for lock" ) ;
29
+ } else {
30
+ println ! ( "warning: build directory locked, waiting for lock" ) ;
31
+ }
25
32
t ! ( build_lock. write( ) )
26
33
}
27
34
} ;
@@ -98,3 +105,27 @@ fn check_version(config: &Config) -> Option<String> {
98
105
99
106
Some ( msg)
100
107
}
108
+
109
+ /// Get the PID of the process which took the write lock by
110
+ /// parsing `/proc/locks`.
111
+ #[ cfg( target_os = "linux" ) ]
112
+ fn get_lock_owner ( f : & std:: path:: Path ) -> Option < u64 > {
113
+ use std:: os:: unix:: fs:: MetadataExt ;
114
+ let lock_inode = std:: fs:: metadata ( f) . ok ( ) ?. ino ( ) ;
115
+ let lockfile = File :: open ( "/proc/locks" ) . ok ( ) ?;
116
+ BufReader :: new ( lockfile) . lines ( ) . find_map ( |line| {
117
+ // pid--vvvvvv vvvvvvv--- inode
118
+ // 21: FLOCK ADVISORY WRITE 359238 08:02:3719774 0 EOF
119
+ let line = line. ok ( ) ?;
120
+ let parts = line. split_whitespace ( ) . collect :: < Vec < _ > > ( ) ;
121
+ let ( pid, inode) = ( parts[ 4 ] . parse :: < u64 > ( ) . ok ( ) ?, & parts[ 5 ] ) ;
122
+ let inode = inode. rsplit_once ( ':' ) ?. 1 . parse :: < u64 > ( ) . ok ( ) ?;
123
+ if inode == lock_inode { Some ( pid) } else { None }
124
+ } )
125
+ }
126
+
127
+ #[ cfg( not( target_os = "linux" ) ) ]
128
+ fn get_lock_owner ( f : & std:: path:: Path ) -> Option < u64 > {
129
+ // FIXME: Implement on other OS's
130
+ None
131
+ }
0 commit comments