internal MemoryMappedViewAccessor(MemoryMappedView view) { Debug.Assert(view != null, "view is null"); _view = view; Initialize(_view.ViewHandle, _view.PointerOffset, _view.Size, MemoryMappedFile.GetFileAccess(_view.Access)); }
public MemoryMappedViewAccessor CreateViewAccessor(long offset, long size, MemoryMappedFileAccess access) { if (offset < 0) { throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum); } if (size < 0) { throw new ArgumentOutOfRangeException(nameof(size), SR.ArgumentOutOfRange_PositiveOrDefaultSizeRequired); } if (access < MemoryMappedFileAccess.ReadWrite || access > MemoryMappedFileAccess.ReadWriteExecute) { throw new ArgumentOutOfRangeException(nameof(access)); } if (IntPtr.Size == 4 && size > uint.MaxValue) { throw new ArgumentOutOfRangeException(nameof(size), SR.ArgumentOutOfRange_CapacityLargerThanLogicalAddressSpaceNotAllowed); } MemoryMappedView view = MemoryMappedView.CreateView(_handle, access, offset, size); return(new MemoryMappedViewAccessor(view)); }
private static unsafe SafeMemoryMappedFileHandle CreateCore( FileStream fileStream, string mapName, HandleInheritability inheritability, MemoryMappedFileAccess access, MemoryMappedFileOptions options, long capacity) { if (mapName != null) { // Named maps are not supported in our Unix implementation. We could support named maps on Linux using // shared memory segments (shmget/shmat/shmdt/shmctl/etc.), but that doesn't work on OSX by default due // to very low default limits on OSX for the size of such objects; it also doesn't support behaviors // like copy-on-write or the ability to control handle inheritability, and reliably cleaning them up // relies on some non-conforming behaviors around shared memory IDs remaining valid even after they've // been marked for deletion (IPC_RMID). We could also support named maps using the current implementation // by not unlinking after creating the backing store, but then the backing stores would remain around // and accessible even after process exit, with no good way to appropriately clean them up. // (File-backed maps may still be used for cross-process communication.) throw CreateNamedMapsNotSupportedException(); } bool ownsFileStream = false; if (fileStream != null) { // This map is backed by a file. Make sure the file's size is increased to be // at least as big as the requested capacity of the map. if (fileStream.Length < capacity) { try { fileStream.SetLength(capacity); } catch (ArgumentException exc) { // If the capacity is too large, we'll get an ArgumentException from SetLength, // but on Windows this same condition is represented by an IOException. throw new IOException(exc.Message, exc); } } } else { // This map is backed by memory-only. With files, multiple views over the same map // will end up being able to share data through the same file-based backing store; // for anonymous maps, we need a similar backing store, or else multiple views would logically // each be their own map and wouldn't share any data. To achieve this, we create a backing object // (either memory or on disk, depending on the system) and use its file descriptor as the file handle. // However, we only do this when the permission is more than read-only. We can't change the size // of an object that has read-only permissions, but we also don't need to worry about sharing // views over a read-only, anonymous, memory-backed map, because the data will never change, so all views // will always see zero and can't change that. In that case, we just use the built-in anonymous support of // the map by leaving fileStream as null. Interop.Sys.MemoryMappedProtections protections = MemoryMappedView.GetProtections(access, forVerification: false); if ((protections & Interop.Sys.MemoryMappedProtections.PROT_WRITE) != 0 && capacity > 0) { ownsFileStream = true; fileStream = CreateSharedBackingObject(protections, capacity); // If the MMF handle should not be inherited, mark the backing object fd as O_CLOEXEC. if (inheritability == HandleInheritability.None) { Interop.CheckIo(Interop.Sys.Fcntl.SetCloseOnExec(fileStream.SafeFileHandle)); } } } return(new SafeMemoryMappedFileHandle(fileStream, ownsFileStream, inheritability, access, options, capacity)); }