[System.Core] Implement MemoryMappedFile.OpenExisting
authorMarius Ungureanu <marius.ungureanu@xamarin.com>
Sat, 24 Jun 2017 18:48:17 +0000 (21:48 +0300)
committerMarek Safar <marek.safar@gmail.com>
Mon, 26 Jun 2017 14:57:31 +0000 (16:57 +0200)
Reuse the existing icall infrastructure to give the same handle back.

This PR implements all OpenExisting methods (with the access rights parameter discarded) and the SafeHandle property.
In the runtime, we don't check the capacity parameter if we try to open a mmap file, and we fallthrough the handle refcount case.

mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedFile.cs
mcs/class/System.Core/Test/System.IO.MemoryMappedFiles/MemoryMappedFileTest.cs
mono/metadata/file-mmap-posix.c
mono/metadata/file-mmap-windows.c

index 4adaaf514febde7d264e247301a62100237a3c0c..45d6c4541eb4535cf5794fac3f65d994d492314d 100644 (file)
@@ -310,19 +310,20 @@ namespace System.IO.MemoryMappedFiles
                [MonoLimitation ("Named mappings scope is process local")]
                public static MemoryMappedFile OpenExisting (string mapName)
                {
-                       throw new NotImplementedException ();
+                       return OpenExisting (mapName, MemoryMappedFileRights.ReadWrite);
                }
 
                [MonoLimitation ("Named mappings scope is process local")]
                public static MemoryMappedFile OpenExisting (string mapName, MemoryMappedFileRights desiredAccessRights)
                {
-                       throw new NotImplementedException ();
+                       return OpenExisting (mapName, desiredAccessRights, HandleInheritability.None);
                }
 
                [MonoLimitation ("Named mappings scope is process local")]
                public static MemoryMappedFile OpenExisting (string mapName, MemoryMappedFileRights desiredAccessRights, HandleInheritability inheritability)
                {
-                       throw new NotImplementedException ();
+                       // FIXME: Actually use desiredAccessRights
+                       return CoreShmCreate (mapName, 0, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, null, inheritability, FileMode.Open);
                }
 
                public MemoryMappedViewStream CreateViewStream ()
@@ -393,10 +394,9 @@ namespace System.IO.MemoryMappedFiles
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
                public SafeMemoryMappedFileHandle SafeMemoryMappedFileHandle {
                        get {
-                               throw new NotImplementedException ();
+                               return handle;
                        }
                }
 
index c192c397fa82fda4a06ff5418e4c0aab4e5bfca4..e533f0144b5434e2e9168f3e3cfc53c8f369b917 100644 (file)
@@ -301,9 +301,12 @@ namespace MonoTests.System.IO.MemoryMappedFiles {
                        var name = MkNamedMapping ();
                        using (var m0 = MemoryMappedFile.CreateNew(name, 4096, MemoryMappedFileAccess.ReadWrite)) {
                                using (var m1 = MemoryMappedFile.CreateOrOpen (name, 4096, MemoryMappedFileAccess.ReadWrite)) {
-                                       using (MemoryMappedViewAccessor v0 = m0.CreateViewAccessor (), v1 = m1.CreateViewAccessor ()) {
-                                               v0.Write (10, 0x12345);
-                                               Assert.AreEqual (0x12345, v1.ReadInt32 (10));
+                                       using (var m2 = MemoryMappedFile.OpenExisting (name)) {
+                                               using (MemoryMappedViewAccessor v0 = m0.CreateViewAccessor (), v1 = m1.CreateViewAccessor (), v2 = m2.CreateViewAccessor ()) {
+                                                       v0.Write (10, 0x12345);
+                                                       Assert.AreEqual (0x12345, v1.ReadInt32 (10));
+                                                       Assert.AreEqual (0x12345, v2.ReadInt32 (10));
+                                               }
                                        }
                                }
                        }
@@ -466,5 +469,13 @@ namespace MonoTests.System.IO.MemoryMappedFiles {
                                }
                        }
                }
+
+               [Test]
+               public void OpenExistingWithNoExistingThrows()
+               {
+                       Assert.Throws<FileNotFoundException>(() => {
+                               MemoryMappedFile.OpenExisting (MkNamedMapping ());
+                       });
+               }
        }
 }
index c6c906bc098faaf23feb34e389b48fd046289940..3c971a091b5f907ea864a239e9e118b5f121e162 100644 (file)
@@ -303,7 +303,7 @@ static void*
 open_memory_map (const char *c_mapName, int mode, gint64 *capacity, int access, int options, int *ioerror)
 {
        MmapHandle *handle;
-       if (*capacity <= 0) {
+       if (*capacity <= 0 && mode != FILE_MODE_OPEN) {
                *ioerror = CAPACITY_MUST_BE_POSITIVE;
                return NULL;
        }
index e6d8cfd9a1edb0cbe737d9d41df80cded04387cf..59abd6686ffe192285513af90cccac7c23becd7a 100644 (file)
@@ -140,7 +140,7 @@ static void *open_handle (void *handle, MonoString *mapName, int mode, gint64 *c
        HANDLE result = NULL;
 
        if (handle == INVALID_HANDLE_VALUE) {
-               if (*capacity <= 0) {
+               if (*capacity <= 0 && mode != FILE_MODE_OPEN) {
                        *error = CAPACITY_MUST_BE_POSITIVE;
                        return NULL;
                }