5
5
//! parent directory, and otherwise documentation can be found throughout the `build`
6
6
//! directory in each respective module.
7
7
8
- use std:: env;
8
+ use std:: fs:: OpenOptions ;
9
+ use std:: io:: Write ;
10
+ use std:: { env, fs, process} ;
9
11
10
12
#[ cfg( all( any( unix, windows) , not( target_os = "solaris" ) ) ) ]
11
13
use bootstrap:: t;
@@ -20,22 +22,32 @@ fn main() {
20
22
#[ cfg( all( any( unix, windows) , not( target_os = "solaris" ) ) ) ]
21
23
let _build_lock_guard;
22
24
#[ 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
23
27
{
24
28
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) ) ) ;
26
36
_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
+ }
28
41
err => {
29
42
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
36
47
}
37
48
} ;
38
49
}
50
+
39
51
#[ cfg( any( not( any( unix, windows) ) , target_os = "solaris" ) ) ]
40
52
println ! ( "warning: file locking not supported for target, not locking build directory" ) ;
41
53
@@ -108,30 +120,3 @@ fn check_version(config: &Config) -> Option<String> {
108
120
109
121
Some ( msg)
110
122
}
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