diff --git a/ChangeLog b/ChangeLog index 74fdba9fc..ddf5a370c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,12 @@ * Source/NSScanner.m: initialisation fix pointed out by David Ayer * Source/NSBundle.m: fix for getting class from gnustep bundle + * Source/NSConnection.m: thread deadlock fix based on probelm and + solution supplied by Wim Oudshoorn + * Source/NSArchiver.m: + * Source/NSKeyedArchiver.m: + * Source/NSPortCoder.m: Fix possible problem on 64bit CPUs reported + by Wim. 2006-08-16 Richard Frith-Macdonald diff --git a/Source/NSArchiver.m b/Source/NSArchiver.m index 5a6f6f179..a4fd51e5b 100644 --- a/Source/NSArchiver.m +++ b/Source/NSArchiver.m @@ -34,7 +34,7 @@ #define GSI_MAP_RETAIN_VAL(M, X) #define GSI_MAP_RELEASE_VAL(M, X) #define GSI_MAP_HASH(M, X) ((X).uint) -#define GSI_MAP_EQUAL(M, X,Y) ((X).uint == (Y).uint) +#define GSI_MAP_EQUAL(M, X,Y) ((X).ptr == (Y).ptr) #define GSI_MAP_NOCLEAN 1 #include "GNUstepBase/GSIMap.h" diff --git a/Source/NSConnection.m b/Source/NSConnection.m index 8885becc5..12161781a 100644 --- a/Source/NSConnection.m +++ b/Source/NSConnection.m @@ -3613,23 +3613,28 @@ static void callEncoder (DOContext *ctxt) */ + (void) _threadWillExit: (NSNotification*)notification { - NSRunLoop *runLoop = GSRunLoopForThread([notification object]); + NSRunLoop *runLoop = GSRunLoopForThread ([notification object]); if (runLoop != nil) { - NSHashEnumerator enumerator; + NSEnumerator *enumerator; NSConnection *c; - M_LOCK(connection_table_gate); - enumerator = NSEnumerateHashTable(connection_table); - while ((c = (NSConnection*)NSNextHashEnumeratorItem(&enumerator)) != nil) + M_LOCK (connection_table_gate); + enumerator = [NSAllHashTableObjects(connection_table) objectEnumerator]; + M_UNLOCK (connection_table_gate); + + /* + * We enumerate an array copy of the contents of the hash table + * as we know we can do that safely outside the locked region. + * The temporary array and the enumerator are autoreleased and + * will be deallocated with the threads autorelease pool. + */ + while ((c = [enumerator nextObject]) != nil) { [c removeRunLoop: runLoop]; } - NSEndHashTableEnumeration(&enumerator); - M_UNLOCK(connection_table_gate); } } - @end diff --git a/Source/NSKeyedArchiver.m b/Source/NSKeyedArchiver.m index b0b14b8fe..128d6e287 100644 --- a/Source/NSKeyedArchiver.m +++ b/Source/NSKeyedArchiver.m @@ -42,7 +42,7 @@ #define GSI_MAP_RETAIN_VAL(M, X) #define GSI_MAP_RELEASE_VAL(M, X) #define GSI_MAP_HASH(M, X) ((X).uint) -#define GSI_MAP_EQUAL(M, X,Y) ((X).uint == (Y).uint) +#define GSI_MAP_EQUAL(M, X,Y) ((X).ptr == (Y).ptr) #undef GSI_MAP_NOCLEAN #include "GNUstepBase/GSIMap.h" diff --git a/Source/NSPortCoder.m b/Source/NSPortCoder.m index 7c4928055..83883ffa1 100644 --- a/Source/NSPortCoder.m +++ b/Source/NSPortCoder.m @@ -59,7 +59,7 @@ #define GSI_MAP_RETAIN_VAL(M, X) #define GSI_MAP_RELEASE_VAL(M, X) #define GSI_MAP_HASH(M, X) ((X).uint) -#define GSI_MAP_EQUAL(M, X,Y) ((X).uint == (Y).uint) +#define GSI_MAP_EQUAL(M, X,Y) ((X).ptr == (Y).ptr) #define GSI_MAP_NOCLEAN 1 #include "GNUstepBase/GSIMap.h"