55//! parent directory, and otherwise documentation can be found throughout the `build`
66//! directory in each respective module.
77
8- use std:: env;
8+ use std:: fs:: OpenOptions ;
9+ use std:: io:: Write ;
10+ use std:: { env, fs, process} ;
911
1012#[ cfg( all( any( unix, windows) , not( target_os = "solaris" ) ) ) ]
1113use bootstrap:: t;
@@ -20,22 +22,32 @@ fn main() {
2022 #[ cfg( all( any( unix, windows) , not( target_os = "solaris" ) ) ) ]
2123 let _build_lock_guard;
2224 #[ cfg( all( any( unix, windows) , not( target_os = "solaris" ) ) ) ]
25+ // Display PID of process holding the lock
26+ // PID will be stored in a lock file
2327 {
2428 let path = config. out . join ( "lock" ) ;
25- build_lock = fd_lock:: RwLock :: new ( t ! ( std:: fs:: File :: create( & path) ) ) ;
29+ let pid = match fs:: read_to_string ( & path) {
30+ Ok ( contents) => contents,
31+ Err ( _) => String :: new ( ) ,
32+ } ;
33+
34+ build_lock =
35+ fd_lock:: RwLock :: new ( t ! ( OpenOptions :: new( ) . write( true ) . create( true ) . open( & path) ) ) ;
2636 _build_lock_guard = match build_lock. try_write ( ) {
27- Ok ( lock) => lock,
37+ Ok ( mut lock) => {
38+ t ! ( lock. write( & process:: id( ) . to_string( ) . as_ref( ) ) ) ;
39+ lock
40+ }
2841 err => {
2942 drop ( err) ;
30- if let Some ( pid) = get_lock_owner ( & path) {
31- println ! ( "warning: build directory locked by process {pid}, waiting for lock" ) ;
32- } else {
33- println ! ( "warning: build directory locked, waiting for lock" ) ;
34- }
35- t ! ( build_lock. write( ) )
43+ println ! ( "warning: build directory locked by process {pid}, waiting for lock" ) ;
44+ let mut lock = t ! ( build_lock. write( ) ) ;
45+ t ! ( lock. write( & process:: id( ) . to_string( ) . as_ref( ) ) ) ;
46+ lock
3647 }
3748 } ;
3849 }
50+
3951 #[ cfg( any( not( any( unix, windows) ) , target_os = "solaris" ) ) ]
4052 println ! ( "warning: file locking not supported for target, not locking build directory" ) ;
4153
@@ -108,30 +120,3 @@ fn check_version(config: &Config) -> Option<String> {
108120
109121 Some ( msg)
110122}
111-
112- /// Get the PID of the process which took the write lock by
113- /// parsing `/proc/locks`.
114- #[ cfg( target_os = "linux" ) ]
115- fn get_lock_owner ( f : & std:: path:: Path ) -> Option < u64 > {
116- use std:: fs:: File ;
117- use std:: io:: { BufRead , BufReader } ;
118- use std:: os:: unix:: fs:: MetadataExt ;
119-
120- let lock_inode = std:: fs:: metadata ( f) . ok ( ) ?. ino ( ) ;
121- let lockfile = File :: open ( "/proc/locks" ) . ok ( ) ?;
122- BufReader :: new ( lockfile) . lines ( ) . find_map ( |line| {
123- // pid--vvvvvv vvvvvvv--- inode
124- // 21: FLOCK ADVISORY WRITE 359238 08:02:3719774 0 EOF
125- let line = line. ok ( ) ?;
126- let parts = line. split_whitespace ( ) . collect :: < Vec < _ > > ( ) ;
127- let ( pid, inode) = ( parts[ 4 ] . parse :: < u64 > ( ) . ok ( ) ?, & parts[ 5 ] ) ;
128- let inode = inode. rsplit_once ( ':' ) ?. 1 . parse :: < u64 > ( ) . ok ( ) ?;
129- if inode == lock_inode { Some ( pid) } else { None }
130- } )
131- }
132-
133- #[ cfg( not( any( target_os = "linux" , target_os = "solaris" ) ) ) ]
134- fn get_lock_owner ( _: & std:: path:: Path ) -> Option < u64 > {
135- // FIXME: Implement on other OS's
136- None
137- }
0 commit comments