Esempio n. 1
0
        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)
                {
                    fileStream.SetLength(capacity);
                }
            }
            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.libc.MemoryMappedProtections protections = MemoryMappedView.GetProtections(access, forVerification: false);
                if ((protections & Interop.libc.MemoryMappedProtections.PROT_WRITE) != 0 && capacity > 0)
                {
                    ownsFileStream = true;
                    fileStream     = CreateSharedBackingObject(protections, capacity);
                }
            }

            return(new SafeMemoryMappedFileHandle(fileStream, ownsFileStream, inheritability, access, options, capacity));
        }
Esempio n. 2
0
        private static unsafe SafeMemoryMappedFileHandle CreateCore(
            FileStream fileStream, string mapName,
            HandleInheritability inheritability, MemoryMappedFileAccess access,
            MemoryMappedFileOptions options, long capacity)
        {
            if (mapName != null)
            {
                // TODO: We currently do not support named maps.  We could possibly support
                // named maps in the future by using shm_open / shm_unlink, as we do for
                // giving internal names to anonymous maps.  Issues to work through will include
                // dealing with permissions, passing information from the creator of the
                // map to another opener of it, etc.
                throw CreateNamedMapsNotSupportedException();
            }

            SafeFileHandle fileHandle = null;

            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.
                fileHandle = fileStream.SafeFileHandle;
                if (fileStream.Length < capacity)
                {
                    fileStream.SetLength(capacity);
                }
            }
            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 POSIX shared
                // memory object 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 ftruncate to increase the size of a shared memory
                // 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 fileHandle as null.
                Interop.libc.MemoryMappedProtections protections = MemoryMappedView.GetProtections(access, forVerification: false);
                if ((protections & Interop.libc.MemoryMappedProtections.PROT_WRITE) != 0 && capacity > 0)
                {
                    mapName    = "/AnonCoreFxMemMap_" + Guid.NewGuid().ToString("N"); // unique name must start with "/" and be < NAME_MAX length
                    fileHandle = CreateNewSharedMemoryObject(mapName, protections, capacity);
                }
            }

            return(new SafeMemoryMappedFileHandle(mapName, fileHandle, inheritability, access, options, capacity));
        }