@@ -94,19 +94,9 @@ private static bool DirectoryExists(string fullPath)
9494 return ( ( fileinfo . Mode & Interop . Sys . FileTypes . S_IFMT ) == Interop . Sys . FileTypes . S_IFDIR ) ;
9595 }
9696
97- /// <summary>Opens a SafeFileHandle for a file descriptor created by a provided delegate.</summary>
98- /// <param name="fdFunc">
99- /// The function that creates the file descriptor. Returns the file descriptor on success, or an invalid
100- /// file descriptor on error with Marshal.GetLastWin32Error() set to the error code.
101- /// </param>
102- /// <returns>The created SafeFileHandle.</returns>
103- internal static SafeFileHandle Open ( Func < SafeFileHandle > fdFunc )
104- {
105- SafeFileHandle handle = Interop . CheckIo ( fdFunc ( ) ) ;
106-
107- Debug . Assert ( ! handle . IsInvalid , "File descriptor is invalid" ) ;
108- return handle ;
109- }
97+ // Each thread will have its own copy. This prevents race conditions if the handle had the last error.
98+ [ ThreadStatic ]
99+ internal static Interop . ErrorInfo ? t_lastCloseErrorInfo ;
110100
111101 protected override bool ReleaseHandle ( )
112102 {
@@ -122,7 +112,10 @@ protected override bool ReleaseHandle()
122112 // to retry, as the descriptor could actually have been closed, been subsequently reassigned, and
123113 // be in use elsewhere in the process. Instead, we simply check whether the call was successful.
124114 int result = Interop . Sys . Close ( handle ) ;
125- Debug . Assert ( result == 0 , $ "Close failed with result { result } and error { Interop . Sys . GetLastErrorInfo ( ) } ") ;
115+ if ( result != 0 )
116+ {
117+ t_lastCloseErrorInfo = Interop . Sys . GetLastErrorInfo ( ) ;
118+ }
126119 return result == 0 ;
127120 }
128121
0 commit comments