11use std:: fs;
22use std:: path:: { Path , PathBuf } ;
33use std:: process:: { Command , Stdio } ;
4+ use std:: sync:: { Mutex , OnceLock } ;
45use std:: time:: { Duration , Instant } ;
56
67use anyhow:: { Context , Result } ;
@@ -1108,6 +1109,10 @@ fn run_cpp_binary(binary: &Path) -> Result<std::process::Output> {
11081109}
11091110
11101111fn ensure_global_cpp_pch ( compiler : & Path ) -> Option < PathBuf > {
1112+ static PCH_BUILD_LOCK : OnceLock < Mutex < ( ) > > = OnceLock :: new ( ) ;
1113+ let lock = PCH_BUILD_LOCK . get_or_init ( || Mutex :: new ( ( ) ) ) ;
1114+ let _guard = lock. lock ( ) . ok ( ) ?;
1115+
11111116 let cache_dir = std:: env:: temp_dir ( ) . join ( "run-compile-cache" ) ;
11121117 std:: fs:: create_dir_all ( & cache_dir) . ok ( ) ?;
11131118 let header = cache_dir. join ( "run_cpp_pch.hpp" ) ;
@@ -1122,7 +1127,9 @@ fn ensure_global_cpp_pch(compiler: &Path) -> Option<PathBuf> {
11221127 "#include <algorithm>\n " ,
11231128 "#include <utility>\n "
11241129 ) ;
1125- std:: fs:: write ( & header, contents) . ok ( ) ?;
1130+ let tmp_header = cache_dir. join ( format ! ( "run_cpp_pch.hpp.tmp.{}" , std:: process:: id( ) ) ) ;
1131+ std:: fs:: write ( & tmp_header, contents) . ok ( ) ?;
1132+ std:: fs:: rename ( & tmp_header, & header) . ok ( ) ?;
11261133 }
11271134 let needs_build = if !gch. exists ( ) {
11281135 true
@@ -1132,21 +1139,24 @@ fn ensure_global_cpp_pch(compiler: &Path) -> Option<PathBuf> {
11321139 h > g
11331140 } ;
11341141 if needs_build {
1142+ let tmp_gch = cache_dir. join ( format ! ( "run_cpp_pch.hpp.gch.tmp.{}" , std:: process:: id( ) ) ) ;
11351143 let mut pch_cmd = compiler_command ( compiler) ;
11361144 let out = pch_cmd
11371145 . arg ( "-std=c++17" )
11381146 . arg ( "-x" )
11391147 . arg ( "c++-header" )
11401148 . arg ( & header)
11411149 . arg ( "-o" )
1142- . arg ( & gch )
1150+ . arg ( & tmp_gch )
11431151 . stdout ( Stdio :: piped ( ) )
11441152 . stderr ( Stdio :: piped ( ) )
11451153 . output ( )
11461154 . ok ( ) ?;
11471155 if !out. status . success ( ) {
1156+ let _ = std:: fs:: remove_file ( & tmp_gch) ;
11481157 return None ;
11491158 }
1159+ std:: fs:: rename ( & tmp_gch, & gch) . ok ( ) ?;
11501160 }
11511161 Some ( header)
11521162}
0 commit comments