/// <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);
        }
Beispiel #2
0
        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();
                }
            }
        }
Beispiel #4
0
        /// <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();
 }