/// <summary> /// Used by the OpenExisting factory method group and by CreateOrOpen if access is write. /// We'll throw an ArgumentException if the file mapping object didn't exist and the /// caller used CreateOrOpen since Create isn't valid with Write access /// </summary> private static SafeMemoryMappedFileHandle OpenCore( string mapName, HandleInheritability inheritability, int desiredAccessRights, bool createOrOpen) { SafeMemoryMappedFileHandle handle = Interop.OpenFileMapping( desiredAccessRights, (inheritability & HandleInheritability.Inheritable) != 0, mapName); int lastError = Marshal.GetLastWin32Error(); if (handle.IsInvalid) { handle.Dispose(); if (createOrOpen && (lastError == Interop.Errors.ERROR_FILE_NOT_FOUND)) { throw new ArgumentException(SR.Argument_NewMMFWriteAccessNotAllowed, "access"); } else { throw Win32Marshal.GetExceptionForWin32Error(lastError); } } return(handle); }
private static SafeMemoryMappedFileHandle CreateCore(SafeFileHandle fileHandle, String mapName, HandleInheritability inheritability, MemoryMappedFileSecurity memoryMappedFileSecurity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, Int64 capacity) { SafeMemoryMappedFileHandle handle = null; Object pinningHandle; UnsafeNativeMethods.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(inheritability, memoryMappedFileSecurity, out pinningHandle); // split the long into two ints Int32 capacityLow = (Int32)(capacity & 0x00000000FFFFFFFFL); Int32 capacityHigh = (Int32)(capacity >> 32); try { handle = UnsafeNativeMethods.CreateFileMapping(fileHandle, secAttrs, GetPageAccess(access) | (int)options, capacityHigh, capacityLow, mapName); Int32 errorCode = Marshal.GetLastWin32Error(); if (!handle.IsInvalid && errorCode == UnsafeNativeMethods.ERROR_ALREADY_EXISTS) { handle.Dispose(); __Error.WinIOError(errorCode, String.Empty); } else if (handle.IsInvalid) { __Error.WinIOError(errorCode, String.Empty); } } finally { if (pinningHandle != null) { GCHandle pinHandle = (GCHandle)pinningHandle; pinHandle.Free(); } } return(handle); }
public void Dispose() { if (!m_disposed) { m_disposed = true; if (m_viewHandle != null) { if (m_baseAddress != null) { m_viewHandle.ReleasePointer(); } m_viewHandle.Dispose(); } if (m_mapHandle != null) { m_mapHandle.Dispose(); } if (m_file != null) { m_file.Dispose(); } } }
/// <summary> /// Used by the CreateOrOpen factory method groups. /// </summary> private static SafeMemoryMappedFileHandle CreateOrOpenCore( string mapName, HandleInheritability inheritability, MemoryMappedFileAccess access, MemoryMappedFileOptions options, long capacity) { // Try to open the file if it exists -- this requires a bit more work. Loop until we can // either create or open a memory mapped file up to a timeout. CreateFileMapping may fail // if the file exists and we have non-null security attributes, in which case we need to // use OpenFileMapping. But, there exists a race condition because the memory mapped file // may have closed between the two calls -- hence the loop. // // The retry/timeout logic increases the wait time each pass through the loop and times // out in approximately 1.4 minutes. If after retrying, a MMF handle still hasn't been opened, // throw an InvalidOperationException. Debug.Assert(access != MemoryMappedFileAccess.Write, "Callers requesting write access shouldn't try to create a mmf"); SafeMemoryMappedFileHandle handle = null; Interop.Kernel32.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(inheritability); int waitRetries = 14; //((2^13)-1)*10ms == approximately 1.4mins int waitSleep = 0; // keep looping until we've exhausted retries or break as soon we get valid handle while (waitRetries > 0) { // try to create handle = Interop.CreateFileMapping(new IntPtr(-1), ref secAttrs, GetPageAccess(access) | (int)options, capacity, mapName); if (!handle.IsInvalid) { break; } else { handle.Dispose(); int createErrorCode = Marshal.GetLastWin32Error(); if (createErrorCode != Interop.Errors.ERROR_ACCESS_DENIED) { throw Win32Marshal.GetExceptionForWin32Error(createErrorCode); } } // try to open handle = Interop.OpenFileMapping(GetFileMapAccess(access), (inheritability & HandleInheritability.Inheritable) != 0, mapName); // valid handle if (!handle.IsInvalid) { break; } // didn't get valid handle; have to retry else { handle.Dispose(); int openErrorCode = Marshal.GetLastWin32Error(); if (openErrorCode != Interop.Errors.ERROR_FILE_NOT_FOUND) { throw Win32Marshal.GetExceptionForWin32Error(openErrorCode); } // increase wait time --waitRetries; if (waitSleep == 0) { waitSleep = 10; } else { Thread.Sleep(waitSleep); waitSleep *= 2; } } } // finished retrying but couldn't create or open if (handle == null || handle.IsInvalid) { throw new InvalidOperationException(SR.InvalidOperation_CantCreateFileMapping); } return(handle); }
public void Dispose() { ums?.Dispose(); memBuffer?.Dispose(); accessor?.Dispose(); }