66//! directory in each respective module.
77
88use std:: env;
9+ use std:: fs:: File ;
10+ use std:: io:: { BufRead , BufReader } ;
911
1012use bootstrap:: { t, Build , Config , Subcommand , VERSION } ;
1113
@@ -16,12 +18,17 @@ fn main() {
1618 let mut build_lock;
1719 let _build_lock_guard;
1820 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) ) ) ;
2023 _build_lock_guard = match build_lock. try_write ( ) {
2124 Ok ( lock) => lock,
2225 err => {
23- println ! ( "warning: build directory locked, waiting for lock" ) ;
2426 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+ }
2532 t ! ( build_lock. write( ) )
2633 }
2734 } ;
@@ -98,3 +105,27 @@ fn check_version(config: &Config) -> Option<String> {
98105
99106 Some ( msg)
100107}
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