[Kde-bindings] KDE/kdebindings/csharp/qyoto

Arno Rehn kde at arnorehn.de
Sat Dec 20 13:25:32 UTC 2008


SVN commit 899251 by arnorehn:

* Revert pointerMap to a Dictionary. The crash that was reported by Eric
  occured because Dictionary isn't thread-safe. Enclose the operations on
  pointerMap in a lock (pointerMap) { ... } to synchronise the threads and
  prevent the crash.

CCMAIL: kde-bindings at kde.org
CCMAIL: eric at extremeboredom.net



 M  +7 -0      ChangeLog  
 M  +44 -38    src/SmokeMarshallers.cs  


--- trunk/KDE/kdebindings/csharp/qyoto/ChangeLog #899250:899251
@@ -1,3 +1,10 @@
+2008-12-20  Arno Rehn  <arno at arnorehn.de>
+
+	* Revert pointerMap to a Dictionary. The crash that was reported by Eric
+	  occured because Dictionary isn't thread-safe. Enclose the operations on
+	  pointerMap in a lock (pointerMap) { ... } to synchronise the threads and
+	  prevent the crash.
+
 2008-12-19  Richard Dale  <richard.j.dale at gmail.com>
 	* When the construct_copy() function was used to copy and instance, it
 	  wasn't initializing the binding for the new instance. This caused a
--- trunk/KDE/kdebindings/csharp/qyoto/src/SmokeMarshallers.cs #899250:899251
@@ -329,15 +329,13 @@
 
 		// The key is an IntPtr corresponding to the address of the C++ instance,
 		// and the value is a WeakReference to the C# instance.
-		
-		// temporarily use a hashtable since Mono's Dictionary implementation seems buggy. And why do we fix the
-		// capacity to 2179?
-// 		static private Dictionary<IntPtr, WeakReference> pointerMap = new Dictionary<IntPtr, WeakReference>(2179);
-		static private Hashtable pointerMap = new Hashtable();
+		static private Dictionary<IntPtr, WeakReference> pointerMap = new Dictionary<IntPtr, WeakReference>();
 
 		public static void AddGlobalRef(IntPtr instancePtr, IntPtr ptr) {
 			Object instance = ((GCHandle) instancePtr).Target;
-			globalReferenceMap[ptr] = instance;
+			lock (globalReferenceMap) {
+				globalReferenceMap[ptr] = instance;
+			}
 #if DEBUG
 			if ((QDebug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
 				Console.WriteLine("AddGlobalRef() Creating global reference 0x{0:x8} -> {1}", (int) ptr, instance);
@@ -347,55 +345,65 @@
 
 		public static void RemoveGlobalRef(IntPtr instancePtr, IntPtr ptr) {
 			Object instance = ((GCHandle) instancePtr).Target;
-			if (globalReferenceMap.ContainsKey(ptr)) {
+			lock (globalReferenceMap) {
+				if (globalReferenceMap.ContainsKey(ptr)) {
 #if DEBUG
-				if ((QDebug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
-					object reference;
-					if (globalReferenceMap.TryGetValue(ptr, out reference)) {
-						Console.WriteLine("RemoveGlobalRef() Removing global reference 0x{0:x8} -> {1}", (int) ptr, reference);
+					if ((QDebug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
+						object reference;
+						if (globalReferenceMap.TryGetValue(ptr, out reference)) {
+							Console.WriteLine("RemoveGlobalRef() Removing global reference 0x{0:x8} -> {1}", (int) ptr, reference);
+						}
 					}
+#endif
+					globalReferenceMap.Remove(ptr);
 				}
-#endif
-				globalReferenceMap.Remove(ptr);
 			}
 		}
 
 		public static void MapPointer(IntPtr ptr, IntPtr instancePtr, bool createGlobalReference) {
-			Object instance = ((GCHandle) instancePtr).Target;
-			WeakReference weakRef = new WeakReference(instance);
-			pointerMap[ptr] = weakRef;
+			lock (pointerMap) {
+				Object instance = ((GCHandle) instancePtr).Target;
+				WeakReference weakRef = new WeakReference(instance);
+				pointerMap[ptr] = weakRef;
 #if DEBUG
-			if ((QDebug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
-				Console.WriteLine("MapPointer() Creating weak reference 0x{0:x8} -> {1}", (int) ptr, instance);
-			}
+				if ((QDebug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
+					Console.WriteLine("MapPointer() Creating weak reference 0x{0:x8} -> {1}", (int) ptr, instance);
+				}
 #endif
-			if (createGlobalReference) {
-				globalReferenceMap[ptr] = instance;
+				if (createGlobalReference) {
+					lock (globalReferenceMap) {
+						globalReferenceMap[ptr] = instance;
 #if DEBUG
-				if ((QDebug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
-					Console.WriteLine("MapPointer() Creating global reference 0x{0:x8} -> {1}", (int) ptr, instance);
+						if ((QDebug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
+							Console.WriteLine("MapPointer() Creating global reference 0x{0:x8} -> {1}", (int) ptr, instance);
+						}
+#endif
+					}
 				}
-#endif
 			}
 		}
 		
 		public static void UnmapPointer(IntPtr ptr) {
+			lock (pointerMap) {
 #if DEBUG
-			if ((QDebug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
-				Console.WriteLine("UnmapPointer() Removing weak reference 0x{0:x8}", (int) ptr);
-			}
+				if ((QDebug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
+					Console.WriteLine("UnmapPointer() Removing weak reference 0x{0:x8}", (int) ptr);
+				}
 #endif
-			pointerMap.Remove(ptr);
-			if (globalReferenceMap.ContainsKey(ptr)) {
+				pointerMap.Remove(ptr);
+				lock (globalReferenceMap) {
+					if (globalReferenceMap.ContainsKey(ptr)) {
 #if DEBUG
-				if ((QDebug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
-					object reference;
-					if (globalReferenceMap.TryGetValue(ptr, out reference)) {
-						Console.WriteLine("UnmapPointer() Removing global reference 0x{0:x8} -> {1}", (int) ptr, reference);
+						if ((QDebug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
+							object reference;
+							if (globalReferenceMap.TryGetValue(ptr, out reference)) {
+								Console.WriteLine("UnmapPointer() Removing global reference 0x{0:x8} -> {1}", (int) ptr, reference);
+							}
+						}
+#endif
+						globalReferenceMap.Remove(ptr);
 					}
 				}
-#endif
-				globalReferenceMap.Remove(ptr);
 			}
 		}
 		
@@ -403,7 +411,7 @@
 		// of a Qyoto class and therefore could have custom slots or overriden methods
 		public static IntPtr GetInstance(IntPtr ptr, bool allInstances) {
 			WeakReference weakRef;
-			if (!pointerMap.ContainsKey(ptr)) {
+			if (!pointerMap.TryGetValue(ptr, out weakRef)) {
 #if DEBUG
 				if (	(QDebug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0
 						&& QDebug.debugLevel >= DebugLevel.Extensive ) 
@@ -414,8 +422,6 @@
 				return IntPtr.Zero;
 			}
 
-			weakRef = (WeakReference) pointerMap[ptr];
-
 			if (weakRef.IsAlive) {
 #if DEBUG
 				if (	(QDebug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0



More information about the Kde-bindings mailing list