Merge pull request #2237 from xmcclure/container-owner
[mono.git] / mono / metadata / icall.c
index a4a6e9202d65b15ae71f9bc40f5882d79a9d500f..f2d76301c3c7d267a7cf9b3cf318c473b369a905 100644 (file)
@@ -89,7 +89,7 @@
 #include <mono/utils/mono-io-portability.h>
 #include <mono/utils/mono-digest.h>
 #include <mono/utils/bsearch.h>
-#include <mono/utils/mono-mutex.h>
+#include <mono/utils/mono-os-mutex.h>
 #include <mono/utils/mono-threads.h>
 
 #if defined (HOST_WIN32)
@@ -3566,6 +3566,17 @@ property_hash (gconstpointer data)
        return g_str_hash (prop->name);
 }
 
+static gboolean
+method_declaring_signatures_equal (MonoMethod *method1, MonoMethod *method2)
+{
+       if (method1->is_inflated)
+               method1 = ((MonoMethodInflated*) method1)->declaring;
+       if (method2->is_inflated)
+               method2 = ((MonoMethodInflated*) method2)->declaring;
+
+       return mono_metadata_signature_equal (mono_method_signature (method1), mono_method_signature (method2));
+}
+
 static gboolean
 property_equal (MonoProperty *prop1, MonoProperty *prop2)
 {
@@ -3573,10 +3584,26 @@ property_equal (MonoProperty *prop1, MonoProperty *prop2)
        if (!g_str_equal (prop1->name, prop2->name))
                return FALSE;
 
-       if (prop1->get && prop2->get && !mono_metadata_signature_equal (mono_method_signature (prop1->get), mono_method_signature (prop2->get)))
+       /* If we see a property in a generic method, we want to
+          compare the generic signatures, not the inflated signatures
+          because we might conflate two properties that were
+          distinct:
+
+          class Foo<T,U> {
+            public T this[T t] { getter { return t; } } // method 1
+            public U this[U u] { getter { return u; } } // method 2
+          }
+
+          If we see int Foo<int,int>::Item[int] we need to know if
+          the indexer came from method 1 or from method 2, and we
+          shouldn't conflate them.   (Bugzilla 36283)
+       */
+       if (prop1->get && prop2->get && !method_declaring_signatures_equal (prop1->get, prop2->get))
                return FALSE;
-       if (prop1->set && prop2->set && !mono_metadata_signature_equal (mono_method_signature (prop1->set), mono_method_signature (prop2->set)))
+
+       if (prop1->set && prop2->set && !method_declaring_signatures_equal (prop1->set, prop2->set))
                return FALSE;
+
        return TRUE;
 }
 
@@ -7265,19 +7292,19 @@ mono_icall_init (void)
 #endif
 
        icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-       mono_mutex_init (&icall_mutex);
+       mono_os_mutex_init (&icall_mutex);
 }
 
 static void
 mono_icall_lock (void)
 {
-       mono_locks_mutex_acquire (&icall_mutex, IcallLock);
+       mono_locks_os_acquire (&icall_mutex, IcallLock);
 }
 
 static void
 mono_icall_unlock (void)
 {
-       mono_locks_mutex_release (&icall_mutex, IcallLock);
+       mono_locks_os_release (&icall_mutex, IcallLock);
 }
 
 void
@@ -7286,7 +7313,7 @@ mono_icall_cleanup (void)
        g_hash_table_destroy (icall_hash);
        g_hash_table_destroy (jit_icall_hash_name);
        g_hash_table_destroy (jit_icall_hash_addr);
-       mono_mutex_destroy (&icall_mutex);
+       mono_os_mutex_destroy (&icall_mutex);
 }
 
 void