@@ -780,70 +780,25 @@ bool swift::emitLoadedModuleTraceIfNeeded(ModuleDecl *mainModule,
780
780
}
781
781
stringBuffer += " \n " ;
782
782
783
- // If writing to stdout, just perform a normal write.
784
- // If writing to a file, ensure the write is atomic by creating a filesystem lock
785
- // on the output file path.
786
- std::error_code EC;
787
- if (loadedModuleTracePath == " -" ) {
788
- llvm::raw_fd_ostream out (loadedModuleTracePath, EC, llvm::sys::fs::OF_Append);
789
- if (out.has_error () || EC) {
790
- ctxt.Diags .diagnose (SourceLoc (), diag::error_opening_output,
791
- loadedModuleTracePath, EC.message ());
792
- out.clear_error ();
793
- return true ;
794
- }
795
- out << stringBuffer;
796
- } else {
797
- while (1 ) {
798
- // Attempt to lock the output file.
799
- // Only one process is allowed to append to this file at a time.
800
- llvm::LockFileManager Locked (loadedModuleTracePath);
801
- switch (Locked) {
802
- case llvm::LockFileManager::LFS_Error:{
803
- // If we error acquiring a lock, we cannot ensure appends
804
- // to the trace file are atomic - cannot ensure output correctness.
805
- ctxt.Diags .diagnose (SourceLoc (), diag::error_opening_output,
806
- loadedModuleTracePath,
807
- " Failed to acquire filesystem lock" );
808
- Locked.unsafeRemoveLockFile ();
809
- return true ;
810
- }
811
- case llvm::LockFileManager::LFS_Owned: {
812
- // Lock acquired, perform the write and release the lock.
813
- llvm::raw_fd_ostream out (loadedModuleTracePath, EC, llvm::sys::fs::OF_Append);
814
- if (out.has_error () || EC) {
815
- ctxt.Diags .diagnose (SourceLoc (), diag::error_opening_output,
816
- loadedModuleTracePath, EC.message ());
817
- out.clear_error ();
818
- return true ;
819
- }
820
- out << stringBuffer;
821
- out.close ();
822
- Locked.unsafeRemoveLockFile ();
823
- return false ;
824
- }
825
- case llvm::LockFileManager::LFS_Shared: {
826
- // Someone else owns the lock on this file, wait.
827
- switch (Locked.waitForUnlock (256 )) {
828
- case llvm::LockFileManager::Res_Success:
829
- LLVM_FALLTHROUGH;
830
- case llvm::LockFileManager::Res_OwnerDied: {
831
- continue ; // try again to get the lock.
832
- }
833
- case llvm::LockFileManager::Res_Timeout: {
834
- // We could error on timeout to avoid potentially hanging forever, but
835
- // it may be more likely that an interrupted process failed to clear the lock,
836
- // causing other waiting processes to time-out. Let's clear the lock and try
837
- // again right away. If we do start seeing compiler hangs in this location,
838
- // we will need to re-consider.
839
- Locked.unsafeRemoveLockFile ();
840
- continue ;
841
- }
842
- }
843
- break ;
844
- }
845
- }
846
- }
783
+ // Write output via atomic append.
784
+ llvm::vfs::OutputConfig config;
785
+ config.setAppend ().setAtomicWrite ();
786
+ auto outputFile =
787
+ ctxt.getOutputBackend ().createFile (loadedModuleTracePath, config);
788
+
789
+ if (!outputFile) {
790
+ ctxt.Diags .diagnose (SourceLoc (), diag::error_opening_output,
791
+ loadedModuleTracePath,
792
+ toString (outputFile.takeError ()));
793
+ return true ;
794
+ }
795
+
796
+ *outputFile << stringBuffer;
797
+
798
+ if (auto err = outputFile->keep ()) {
799
+ ctxt.Diags .diagnose (SourceLoc (), diag::error_opening_output,
800
+ loadedModuleTracePath, toString (std::move (err)));
801
+ return true ;
847
802
}
848
- return true ;
803
+ return false ;
849
804
}
0 commit comments