From 9eeae92a12b734795890b15c6584ee49f89f311b Mon Sep 17 00:00:00 2001 From: Kevin Malenfant Date: Sun, 13 Apr 2014 10:10:11 -0600 Subject: [PATCH] Addded Finalizer to MemoryMappedFile Memory mapped files were not getting closed. TcImports attaches a dispose function to it's list of disposables to close the map, however, TcImports is never disposed in the "main" fsc.fs functions. So either TcImports needs to be disposed, a finalizer needs to be added to TcImports or a Finalizer needs to be added to MemoryMappedFile. Here the finalizer was added as close to the resources as possible. --- src/absil/ilread.fs | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/absil/ilread.fs b/src/absil/ilread.fs index 2e16eb8a1e..226acc04b6 100755 --- a/src/absil/ilread.fs +++ b/src/absil/ilread.fs @@ -144,6 +144,7 @@ let derefByte (p:nativeint) = NativePtr.read (NativePtr.ofNativeInt p) type MemoryMappedFile(hMap: MemoryMapping.HANDLE, start:nativeint) = + let mutable disposed = false static member Create fileName = //printf "fileName = %s\n" fileName; @@ -162,7 +163,7 @@ type MemoryMappedFile(hMap: MemoryMapping.HANDLE, start:nativeint) = if start.Equals(IntPtr.Zero) then failwithf "MapViewOfFile(0x%08x)" ( Marshal.GetHRForLastWin32Error() ); - MemoryMappedFile(hMap, start) + new MemoryMappedFile(hMap, start) member m.Addr (i:int) : nativeint = start + nativeint i @@ -181,9 +182,7 @@ type MemoryMappedFile(hMap: MemoryMapping.HANDLE, start:nativeint) = member m.ReadUInt16 i = NativePtr.read (NativePtr.ofNativeInt (m.Addr i)) - member m.Close() = - ignore(MemoryMapping.UnmapViewOfFile start); - ignore(MemoryMapping.CloseHandle hMap) + member m.Close() = m.Dispose() member m.CountUtf8String i = let start = m.Addr i @@ -196,6 +195,20 @@ type MemoryMappedFile(hMap: MemoryMapping.HANDLE, start:nativeint) = let n = m.CountUtf8String i new System.String(NativePtr.ofNativeInt (m.Addr i), 0, n, System.Text.Encoding.UTF8) + override m.Finalize() = m.Dispose(false) + + member m.Dispose(_ : bool) = + if not disposed then + ignore(MemoryMapping.UnmapViewOfFile start); + ignore(MemoryMapping.CloseHandle hMap) + disposed <- true + + member m.Dispose() = + m.Dispose(true) + GC.SuppressFinalize(m) + + interface IDisposable with + override m.Dispose() = m.Dispose() type MMapChannel = { mutable mmPos: int;