Merge pull request #1201 from crisdut/fix-win-mono-dependencies
authorZoltan Varga <vargaz@gmail.com>
Fri, 8 Aug 2014 20:46:36 +0000 (22:46 +0200)
committerZoltan Varga <vargaz@gmail.com>
Fri, 8 Aug 2014 20:46:36 +0000 (22:46 +0200)
Adding the mutex header file dependency

13 files changed:
mcs/class/System.IO.Compression.FileSystem/Makefile
mcs/class/System.IO.Compression.FileSystem/System.IO.Compression.FileSystem_test.dll.sources [new file with mode: 0644]
mcs/class/System.IO.Compression.FileSystem/Test/System.IO.Compression.FileSystem/ZipTest.cs [new file with mode: 0644]
mcs/class/System.IO.Compression.FileSystem/ZipFile.cs
mcs/class/System.IO.Compression.FileSystem/ZipFileExtensions.cs
mcs/class/System.IO.Compression.FileSystem/foo/bar.txt [new file with mode: 0644]
mcs/class/System.IO.Compression.FileSystem/foo/foo.txt [new file with mode: 0644]
mcs/class/System.IO.Compression.FileSystem/foo/foobar/bar.txt [new file with mode: 0644]
mcs/class/System.IO.Compression.FileSystem/foo/foobar/foo.txt [new file with mode: 0644]
mcs/class/corlib/System.IO/Path.cs
mcs/class/corlib/Test/System.IO/PathTest.cs
mono/mini/debugger-agent.c
mono/mini/mini.c

index 4e36c8abfd42f045883f3e9a8b0d56ae08116748..764cf083f8b02c82334b097ac0699afa41d57b39 100644 (file)
@@ -4,7 +4,6 @@ include ../../build/rules.make
 
 LIBRARY = System.IO.Compression.FileSystem.dll
 LIB_MCS_FLAGS = /r:System /r:System.IO.Compression.dll
-
-NO_TEST = yes
+TEST_MCS_FLAGS = /r:System /r:System.Core /r:System.IO.Compression.dll
 
 include ../../build/library.make
diff --git a/mcs/class/System.IO.Compression.FileSystem/System.IO.Compression.FileSystem_test.dll.sources b/mcs/class/System.IO.Compression.FileSystem/System.IO.Compression.FileSystem_test.dll.sources
new file mode 100644 (file)
index 0000000..dc67ea0
--- /dev/null
@@ -0,0 +1 @@
+System.IO.Compression.FileSystem/ZipTest.cs
diff --git a/mcs/class/System.IO.Compression.FileSystem/Test/System.IO.Compression.FileSystem/ZipTest.cs b/mcs/class/System.IO.Compression.FileSystem/Test/System.IO.Compression.FileSystem/ZipTest.cs
new file mode 100644 (file)
index 0000000..0354311
--- /dev/null
@@ -0,0 +1,109 @@
+//
+// ZipTest.cs
+//
+// Author:
+//       João Matos <joao.matos@xamarin.com>
+//
+// Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.IO;
+using System.IO.Compression;
+using System.Linq;
+using System.Security.Cryptography;
+using NUnit.Framework;
+
+namespace MonoTests.System.IO.Compression.FileSystem
+{
+       [TestFixture]
+       public class ZipArchiveTests
+       {
+               [TearDown]
+               public void Dispose()
+               {
+                       File.Delete ("foo.zip");
+               }
+
+               [Test]
+               public void ZipCreateFromDirectory()
+               {
+                       if (File.Exists ("foo.zip"))
+                               File.Delete ("foo.zip");
+
+                       ZipFile.CreateFromDirectory ("foo", "foo.zip");
+                       Assert.IsTrue(File.Exists("foo.zip"));
+
+                       using (var archive = new ZipArchive (File.Open ("foo.zip", FileMode.Open),
+                               ZipArchiveMode.Read))
+                       {
+                               Assert.IsNotNull (archive.GetEntry ("foo.txt"));
+                               Assert.IsNotNull (archive.GetEntry ("bar.txt"));
+
+                               Assert.IsNotNull (archive.GetEntry ("foobar/foo.txt"));
+                               Assert.IsNotNull (archive.GetEntry ("foobar/bar.txt"));                         
+                       }
+               }
+
+               [Test]
+               public void ZipCreateFromDirectoryIncludeBase()
+               {
+                       if (File.Exists ("foo.zip"))
+                               File.Delete ("foo.zip");
+
+                       ZipFile.CreateFromDirectory ("foo", "foo.zip", CompressionLevel.Fastest,
+                               includeBaseDirectory: true);
+                       Assert.IsTrue (File.Exists ("foo.zip"));
+
+                       using (var archive = new ZipArchive (File.Open ("foo.zip", FileMode.Open),
+                               ZipArchiveMode.Read))
+                       {
+                               Assert.IsNotNull (archive.GetEntry ("foo/foo.txt"));
+                               Assert.IsNotNull (archive.GetEntry ("foo/bar.txt"));
+
+                               Assert.IsNotNull (archive.GetEntry ("foo/foobar/foo.txt"));
+                               Assert.IsNotNull (archive.GetEntry ("foo/foobar/bar.txt"));                             
+                       }
+               }               
+
+               [Test]
+               public void ZipExtractToDirectory()
+               {
+                       if (Directory.Exists ("extract"))
+                               Directory.Delete ("extract", true);
+
+                       if (File.Exists ("foo.zip"))
+                               File.Delete ("foo.zip");
+
+                       ZipFile.CreateFromDirectory ("foo", "foo.zip");
+
+                       ZipFile.ExtractToDirectory ("foo.zip", "extract");
+                       Assert.IsTrue(Directory.Exists ("extract"));
+
+                       Assert.IsTrue (File.Exists ("extract/foo.txt"));
+                       Assert.IsTrue (File.Exists ("extract/bar.txt"));
+                       Assert.IsTrue (Directory.Exists ("extract/foobar"));
+                       Assert.IsTrue (File.Exists ("extract/foobar/foo.txt"));
+                       Assert.IsTrue (File.Exists ("extract/foobar/bar.txt"));
+
+                       Directory.Delete ("extract", true);
+               }
+       }
+}
index e6016708ab3dd7daa57f7ebf014647783d913d86..eaa3b75230dd928e8121e5a558f3e929c3cc986e 100644 (file)
@@ -2,6 +2,7 @@
 // ZipFile.cs
 //
 // Author:
+//       João Matos <joao.matos@xamarin.com>
 //       Martin Baulig <martin.baulig@xamarin.com>
 //
 // Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)
@@ -28,20 +29,21 @@ using System.Text;
 
 namespace System.IO.Compression
 {
-       [MonoTODO]
        public static class ZipFile
        {
                public static void CreateFromDirectory (
                        string sourceDirectoryName, string destinationArchiveFileName)
                {
-                       throw new NotImplementedException ();
+                       CreateFromDirectory (sourceDirectoryName, destinationArchiveFileName,
+                               CompressionLevel.Fastest, includeBaseDirectory: false);
                }
 
                public static void CreateFromDirectory (
                        string sourceDirectoryName, string destinationArchiveFileName,
                        CompressionLevel compressionLevel, bool includeBaseDirectory)
                {
-                       throw new NotImplementedException ();
+                       CreateFromDirectory (sourceDirectoryName, destinationArchiveFileName,
+                               CompressionLevel.Fastest, includeBaseDirectory, Encoding.UTF8);
                }
 
                public static void CreateFromDirectory (
@@ -51,38 +53,129 @@ namespace System.IO.Compression
                        bool includeBaseDirectory,
                        Encoding entryNameEncoding)
                {
-                       throw new NotImplementedException ();
+                       if (sourceDirectoryName == null)
+                               throw new ArgumentNullException ("sourceDirectoryName");
+
+                       if (destinationArchiveFileName == null)
+                               throw new ArgumentNullException ("destinationArchiveFileName");
+
+                       if (string.IsNullOrWhiteSpace (sourceDirectoryName))
+                               throw new ArgumentException ("sourceDirectoryName");
+                               
+                       if (string.IsNullOrWhiteSpace (destinationArchiveFileName))
+                               throw new ArgumentException ("destinationArchiveFileName");
+
+                       if (entryNameEncoding == Encoding.Unicode ||
+                           entryNameEncoding == Encoding.UTF32 ||
+                           entryNameEncoding == Encoding.UTF7)
+                               throw new ArgumentException ("entryNameEncoding");
+
+                       if (entryNameEncoding == null)
+                               entryNameEncoding = Encoding.UTF8;
+
+                       if (!Directory.Exists (sourceDirectoryName))
+                               throw new DirectoryNotFoundException ("sourceDirectoryName is invalid or does not exist");
+
+                       var sourceDir = new DirectoryInfo (Path.GetFullPath (sourceDirectoryName));
+
+                       string fullBaseName = sourceDir.FullName;
+                       if (includeBaseDirectory && sourceDir.Parent != null)
+                               fullBaseName = sourceDir.Parent.FullName;
+
+                       bool hasEntries = false;
+                       char[] separators = new char[] {
+                               Path.DirectorySeparatorChar,
+                               Path.AltDirectorySeparatorChar
+                       };
+
+                       using (var zipFile = ZipFile.Open (destinationArchiveFileName, ZipArchiveMode.Create,
+                               entryNameEncoding)) {
+                               var entries = sourceDir.EnumerateFileSystemInfos ("*", SearchOption.AllDirectories);
+                               foreach (var entry in entries) {
+                                       hasEntries = true;
+
+                                       int length = entry.FullName.Length - fullBaseName.Length;
+                                       string entryName = entry.FullName.Substring(fullBaseName.Length, length);
+
+                                       entryName = entryName.TrimStart(separators);
+
+                                       if (entry is FileInfo)
+                                               zipFile.CreateEntryFromFile (entry.FullName, entryName, compressionLevel);
+                                       else
+                                               zipFile.CreateEntry (entryName + Path.DirectorySeparatorChar);
+                               }
+
+                               // Create the base directory even if we had no entries
+                               if (includeBaseDirectory && !hasEntries)
+                                       zipFile.CreateEntry(sourceDir.Name + Path.DirectorySeparatorChar);
+                       }
                }
 
                public static void ExtractToDirectory (
                        string sourceArchiveFileName, string destinationDirectoryName)
                {
-                       throw new NotImplementedException ();
+                       ExtractToDirectory (sourceArchiveFileName, destinationDirectoryName,
+                               Encoding.UTF8);
                }
 
                public static void ExtractToDirectory (
                        string sourceArchiveFileName, string destinationDirectoryName,
                        Encoding entryNameEncoding)
                {
-                       throw new NotImplementedException ();
+                       if (sourceArchiveFileName == null)
+                               throw new ArgumentNullException ("sourceArchiveFileName");
+
+                       using (ZipArchive zipArchive = ZipFile.Open(sourceArchiveFileName,
+                               ZipArchiveMode.Read, entryNameEncoding))
+                       {
+                               zipArchive.ExtractToDirectory(destinationDirectoryName);
+                       }
                }
 
                public static ZipArchive Open (
                        string archiveFileName, ZipArchiveMode mode)
                {
-                       throw new NotImplementedException ();
+                       return Open (archiveFileName, mode);
                }
 
                public static ZipArchive Open (
                        string archiveFileName, ZipArchiveMode mode,
                        Encoding entryNameEncoding)
                {
-                       throw new NotImplementedException ();
+                       if (archiveFileName == null)
+                               throw new ArgumentNullException ("archiveFileName");
+
+                       if (string.IsNullOrWhiteSpace (archiveFileName))
+                               throw new ArgumentException ("archiveFileName");
+
+                       FileStream stream;
+
+                       switch (mode) {
+                       case ZipArchiveMode.Read:
+                               if (!File.Exists (archiveFileName))
+                                       throw new FileNotFoundException ();
+                               stream = new FileStream (archiveFileName, FileMode.Open, FileAccess.Read,
+                                       FileShare.Read);
+                               break;
+                       case ZipArchiveMode.Create:
+                               if (File.Exists (archiveFileName))
+                                       throw new IOException ("mode is set to Create but the file already exists");
+                               stream = new FileStream (archiveFileName, FileMode.CreateNew, FileAccess.Write);
+                               break;
+                       case ZipArchiveMode.Update:
+                               stream = new FileStream (archiveFileName, FileMode.OpenOrCreate,
+                                       FileAccess.ReadWrite);
+                               break;
+                       default:
+                               throw new ArgumentOutOfRangeException ();
+                       }
+
+                       return new ZipArchive (stream, mode, false, entryNameEncoding);
                }
 
                public static ZipArchive OpenRead (string archiveFileName)
                {
-                       throw new NotImplementedException ();
+                       return ZipFile.Open (archiveFileName, ZipArchiveMode.Read);
                }
        }
 }
index 1abe0e0e168f167ccb997c41bc24e83c4558d514..07a8448171ed51a1723c1d989ee53ddd071de7f2 100644 (file)
@@ -2,6 +2,7 @@
 // ZipFileExtensions.cs
 //
 // Author:
+//       João Matos <joao.matos@xamarin.com>
 //       Martin Baulig <martin.baulig@xamarin.com>
 //
 // Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)
@@ -27,43 +28,95 @@ using System;
 
 namespace System.IO.Compression
 {
-       [MonoTODO]
        public static class ZipFileExtensions
        {
                public static ZipArchiveEntry CreateEntryFromFile (
                        this ZipArchive destination, string sourceFileName,
                        string entryName)
                {
-                       throw new NotImplementedException ();
+                       return CreateEntryFromFile (destination, sourceFileName, entryName,
+                               CompressionLevel.Fastest);
                }
 
                public static ZipArchiveEntry CreateEntryFromFile (
                        this ZipArchive destination, string sourceFileName,
-                       string entryName, CompressionLevel compressionLevel
-                       )
+                       string entryName, CompressionLevel compressionLevel)
                {
-                       throw new NotImplementedException ();
+                       if (destination == null)
+                               throw new ArgumentNullException ("destination");
+
+                       if (sourceFileName == null)
+                               throw new ArgumentNullException ("sourceFileName");
+
+                       if (entryName == null)
+                               throw new ArgumentNullException ("entryName");
+
+                       ZipArchiveEntry entry;
+                       using (Stream stream = File.Open (sourceFileName, FileMode.Open,
+                               FileAccess.Read, FileShare.Read))
+                       {
+                               var zipArchiveEntry = destination.CreateEntry (entryName, compressionLevel);
+
+                               using (Stream entryStream = zipArchiveEntry.Open ())
+                                       stream.CopyTo (entryStream);
+
+                               entry = zipArchiveEntry;
+                       }
+
+                       return entry;
                }
 
                public static void ExtractToDirectory (
                        this ZipArchive source,
                        string destinationDirectoryName)
                {
-                       throw new NotImplementedException ();
+                       if (source == null)
+                               throw new ArgumentNullException ("source");
+
+                       if (destinationDirectoryName == null)
+                               throw new ArgumentNullException ("destinationDirectoryName");
+
+                       var destDirInfo = Directory.CreateDirectory (destinationDirectoryName);
+                       string fullName = destDirInfo.FullName;
+
+                       foreach (var zipEntry in source.Entries)
+                       {
+                               var fullPath = Path.GetFullPath (Path.Combine (fullName, zipEntry.FullName));
+
+                               var isFileName = Path.GetFileName (fullPath).Length != 0;
+                               var dirPath = isFileName ? Path.GetDirectoryName (fullPath) : fullPath;
+                               Directory.CreateDirectory (dirPath);
+
+                               if (isFileName)
+                                       zipEntry.ExtractToFile (fullPath, false);
+                       }
                }
 
                public static void ExtractToFile (
                        this ZipArchiveEntry source,
                        string destinationFileName)
                {
-                       throw new NotImplementedException ();
+                       ExtractToFile (source, destinationFileName, overwrite: false);
                }
 
                public static void ExtractToFile (
                        this ZipArchiveEntry source, string destinationFileName,
                        bool overwrite)
                {
-                       throw new NotImplementedException ();
+                       if (source == null)
+                               throw new ArgumentNullException ("source");
+
+                       if (destinationFileName == null)
+                               throw new ArgumentNullException ("destinationFileName");
+                               
+                       var mode = overwrite ? FileMode.Create : FileMode.CreateNew;
+                       using (var stream = File.Open (destinationFileName, mode, FileAccess.Write))
+                       {
+                               using (var stream2 = source.Open ())
+                                       stream2.CopyTo(stream);
+                       }
+
+                       File.SetLastWriteTime(destinationFileName, source.LastWriteTime.DateTime);
                }
        }
 }
diff --git a/mcs/class/System.IO.Compression.FileSystem/foo/bar.txt b/mcs/class/System.IO.Compression.FileSystem/foo/bar.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/mcs/class/System.IO.Compression.FileSystem/foo/foo.txt b/mcs/class/System.IO.Compression.FileSystem/foo/foo.txt
new file mode 100644 (file)
index 0000000..257cc56
--- /dev/null
@@ -0,0 +1 @@
+foo
diff --git a/mcs/class/System.IO.Compression.FileSystem/foo/foobar/bar.txt b/mcs/class/System.IO.Compression.FileSystem/foo/foobar/bar.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/mcs/class/System.IO.Compression.FileSystem/foo/foobar/foo.txt b/mcs/class/System.IO.Compression.FileSystem/foo/foobar/foo.txt
new file mode 100644 (file)
index 0000000..e69de29
index 7fdd8d6afc841f722a16f31296aa9ec7141392ba..9364a4c248df9039951a650b952611dc474ba3bc 100644 (file)
@@ -383,7 +383,11 @@ namespace System.IO {
                                                canonicalize = start > 0;
                                        }
 
-                                       path = Directory.InsecureGetCurrentDirectory() + DirectorySeparatorStr + path;
+                                       var cwd = Directory.InsecureGetCurrentDirectory();
+                                       if (cwd.EndsWith(DirectorySeparatorStr))
+                                               path = cwd + path;
+                                       else
+                                               path = cwd + DirectorySeparatorChar + path;                                     
                                } else if (DirectorySeparatorChar == '\\' &&
                                        path.Length >= 2 &&
                                        IsDsc (path [0]) &&
index d0314abe63f450ba02b475f58eba6f6b42b48725..78e95aaffda6a4c133467b82ac8d1b684c43b93b 100644 (file)
@@ -545,6 +545,16 @@ namespace MonoTests.System.IO
                        Assert.AreEqual (Environment.CurrentDirectory, Path.GetFullPath ("."), "#03");
                        Assert.AreEqual (Path.Combine (Environment.CurrentDirectory, "hey"),
                                             Path.GetFullPath ("hey"), "#04");
+                       Assert.AreEqual ("/", Path.GetFullPath ("/"), "#01");
+
+                       string curdir = Directory.GetCurrentDirectory ();
+                       try {
+                               Directory.SetCurrentDirectory ("/");
+                               Assert.AreEqual ("/test.txt", Path.GetFullPath ("test.txt"), "xambug #833");
+                       }
+                       finally {
+                               Directory.SetCurrentDirectory (curdir);
+                       }
                }
 
                [Test]
index b6b9264957d7ffb41373e4db65fb05896c364ff4..6249ed00c66ba26ebb3dc652efcc9ced30b49b7d 100644 (file)
@@ -7758,7 +7758,7 @@ buffer_add_cattr_arg (Buffer *buf, MonoType *t, MonoDomain *domain, MonoObject *
                buffer_add_value (buf, t, mono_object_unbox (val), domain);
 }
 
-static void
+static int
 buffer_add_cattrs (Buffer *buf, MonoDomain *domain, MonoImage *image, MonoClass *attr_klass, MonoCustomAttrInfo *cinfo)
 {
        int i, j;
@@ -7766,7 +7766,7 @@ buffer_add_cattrs (Buffer *buf, MonoDomain *domain, MonoImage *image, MonoClass
 
        if (!cinfo) {
                buffer_add_int (buf, 0);
-               return;
+               return ERR_NONE;
        }
 
        for (i = 0; i < cinfo->num_attrs; ++i) {
@@ -7784,7 +7784,11 @@ buffer_add_cattrs (Buffer *buf, MonoDomain *domain, MonoImage *image, MonoClass
                        MonoError error;
 
                        mono_reflection_create_custom_attr_data_args (image, attr->ctor, attr->data, attr->data_size, &typed_args, &named_args, &arginfo, &error);
-                       g_assert (mono_error_ok (&error));
+                       if (!mono_error_ok (&error)) {
+                               DEBUG(2, fprintf (log_file, "[dbg] mono_reflection_create_custom_attr_data_args () failed with: '%s'\n", mono_error_get_message (&error)));
+                               mono_error_cleanup (&error);
+                               return ERR_LOADER_ERROR;
+                       }
 
                        buffer_add_methodid (buf, domain, attr->ctor);
 
@@ -7827,6 +7831,8 @@ buffer_add_cattrs (Buffer *buf, MonoDomain *domain, MonoImage *image, MonoClass
                        g_free (arginfo);
                }
        }
+
+       return ERR_NONE;
 }
 
 /* FIXME: Code duplication with icall.c */
@@ -8009,7 +8015,9 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint
 
                cinfo = mono_custom_attrs_from_class (klass);
 
-               buffer_add_cattrs (buf, domain, klass->image, attr_klass, cinfo);
+               err = buffer_add_cattrs (buf, domain, klass->image, attr_klass, cinfo);
+               if (err)
+                       return err;
                break;
        }
        case CMD_TYPE_GET_FIELD_CATTRS: {
@@ -8026,7 +8034,9 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint
 
                cinfo = mono_custom_attrs_from_field (klass, field);
 
-               buffer_add_cattrs (buf, domain, klass->image, attr_klass, cinfo);
+               err = buffer_add_cattrs (buf, domain, klass->image, attr_klass, cinfo);
+               if (err)
+                       return err;
                break;
        }
        case CMD_TYPE_GET_PROPERTY_CATTRS: {
@@ -8043,7 +8053,9 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint
 
                cinfo = mono_custom_attrs_from_property (klass, prop);
 
-               buffer_add_cattrs (buf, domain, klass->image, attr_klass, cinfo);
+               err = buffer_add_cattrs (buf, domain, klass->image, attr_klass, cinfo);
+               if (err)
+                       return err;
                break;
        }
        case CMD_TYPE_GET_VALUES:
@@ -8654,7 +8666,9 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
 
                cinfo = mono_custom_attrs_from_method (method);
 
-               buffer_add_cattrs (buf, domain, method->klass->image, attr_klass, cinfo);
+               err = buffer_add_cattrs (buf, domain, method->klass->image, attr_klass, cinfo);
+               if (err)
+                       return err;
                break;
        }
        case CMD_METHOD_MAKE_GENERIC_METHOD: {
index d1d3dbf19302aed9da7168ddd2ca0fbfd33d2da9..0a7bd8a63d0d801cff5dffde459f33f911a9877c 100644 (file)
@@ -6117,18 +6117,11 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
        else
                shared = NULL;
 
-       /*
-        * FIXME: lookup_method_inner requires the loader lock.
-        * FIXME: This is no longer true, can this be dropped ?
-        */
-       mono_loader_lock ();
        mono_domain_lock (target_domain);
 
        /* Check if some other thread already did the job. In this case, we can
        discard the code this thread generated. */
 
-       mono_domain_jit_code_hash_lock (target_domain);
-
        info = lookup_method_inner (target_domain, method, shared);
        if (info) {
                /* We can't use a domain specific method in another domain */
@@ -6137,18 +6130,18 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
 //                     printf("Discarding code for method %s\n", method->name);
                }
        }
-       
        if (code == NULL) {
+               /* The lookup + insert is atomic since this is done inside the domain lock */
+               mono_domain_jit_code_hash_lock (target_domain);
                mono_internal_hash_table_insert (&target_domain->jit_code_hash, cfg->jit_info->d.method, cfg->jit_info);
                mono_domain_jit_code_hash_unlock (target_domain);
+
                code = cfg->native_code;
 
                if (cfg->generic_sharing_context && mono_method_is_generic_sharable (method, FALSE))
                        mono_stats.generics_shared_methods++;
                if (cfg->gsharedvt)
                        mono_stats.gsharedvt_methods++;
-       } else {
-               mono_domain_jit_code_hash_unlock (target_domain);
        }
 
        jinfo = cfg->jit_info;
@@ -6200,7 +6193,6 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
        mono_emit_jit_map (jinfo);
 #endif
        mono_domain_unlock (target_domain);
-       mono_loader_unlock ();
 
        vtable = mono_class_vtable (target_domain, method->klass);
        if (!vtable) {
@@ -6383,7 +6375,9 @@ mono_jit_free_method (MonoDomain *domain, MonoMethod *method)
 
        mono_domain_lock (domain);
        g_hash_table_remove (domain_jit_info (domain)->dynamic_code_hash, method);
+       mono_domain_jit_code_hash_lock (domain);
        mono_internal_hash_table_remove (&domain->jit_code_hash, method);
+       mono_domain_jit_code_hash_unlock (domain);
        g_hash_table_remove (domain_jit_info (domain)->jump_trampoline_hash, method);
        mono_conc_hashtable_remove (domain_jit_info (domain)->runtime_invoke_hash, method);