public static CreateFileMapping ( IntPtr hFile, Kernel32 &securityAttributes, int pageProtection, long maximumSize, string name ) : SafeMemoryMappedFileHandle | ||
hFile | IntPtr | |
securityAttributes | Kernel32 | |
pageProtection | int | |
maximumSize | long | |
name | string | |
return | SafeMemoryMappedFileHandle |
/// <summary> /// Used by the 2 Create factory method groups. A null fileHandle specifies that the /// memory mapped file should not be associated with an existing file on disk (i.e. start /// out empty). /// </summary> private static SafeMemoryMappedFileHandle CreateCore( SafeFileHandle?fileHandle, string?mapName, HandleInheritability inheritability, MemoryMappedFileAccess access, MemoryMappedFileOptions options, long capacity, long fileSize) { Debug.Assert(fileHandle is null || fileSize >= 0); Interop.Kernel32.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(inheritability); if (fileHandle != null) { VerifyMemoryMappedFileAccess(access, capacity, fileSize); } SafeMemoryMappedFileHandle handle = fileHandle != null? Interop.CreateFileMapping(fileHandle, ref secAttrs, GetPageAccess(access) | (int)options, capacity, mapName) : Interop.CreateFileMapping(new IntPtr(-1), ref secAttrs, GetPageAccess(access) | (int)options, capacity, mapName); int errorCode = Marshal.GetLastPInvokeError(); if (!handle.IsInvalid) { if (errorCode == Interop.Errors.ERROR_ALREADY_EXISTS) { handle.Dispose(); throw Win32Marshal.GetExceptionForWin32Error(errorCode); } } else // handle.IsInvalid { handle.Dispose(); throw Win32Marshal.GetExceptionForWin32Error(errorCode); } return(handle); }
/// <summary> /// Used by the 2 Create factory method groups. A null fileHandle specifies that the /// memory mapped file should not be associated with an existing file on disk (i.e. start /// out empty). /// </summary> private static SafeMemoryMappedFileHandle CreateCore( FileStream fileStream, string mapName, HandleInheritability inheritability, MemoryMappedFileAccess access, MemoryMappedFileOptions options, long capacity) { SafeFileHandle fileHandle = fileStream != null ? fileStream.SafeFileHandle : null; Interop.Kernel32.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(inheritability); SafeMemoryMappedFileHandle handle = fileHandle != null? Interop.CreateFileMapping(fileHandle, ref secAttrs, GetPageAccess(access) | (int)options, capacity, mapName) : Interop.CreateFileMapping(new IntPtr(-1), ref secAttrs, GetPageAccess(access) | (int)options, capacity, mapName); int errorCode = Marshal.GetLastWin32Error(); if (!handle.IsInvalid) { if (errorCode == Interop.Errors.ERROR_ALREADY_EXISTS) { handle.Dispose(); throw Win32Marshal.GetExceptionForWin32Error(errorCode); } } else // handle.IsInvalid { handle.Dispose(); throw Win32Marshal.GetExceptionForWin32Error(errorCode); } return(handle); }
/// <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.GetLastPInvokeError(); 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.GetLastPInvokeError(); 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); }