diff --git a/ChangeLog b/ChangeLog index b163629a5..0171732d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2016-07-26 Richard Frith-Macdonald + + * Source/Additions/NSObject+GNUstepbase.m: use separate lock to + protect at exit methods ... avoid conflict/deadlock with multithreaded + notification change. + 2016-07-18 Larry Campbell * Source/NSThread.m: Send notification about becoming multithreaded diff --git a/Source/Additions/GSMime.m b/Source/Additions/GSMime.m index d3230808a..5bfe75eb7 100644 --- a/Source/Additions/GSMime.m +++ b/Source/Additions/GSMime.m @@ -123,6 +123,7 @@ static Class documentClass = 0; static Class headerClass = 0; static BOOL oldStyleFolding = NO; +static NSString *text7bitEncoding = @"quoted-printable"; typedef BOOL (*boolIMP)(id, SEL, id); @@ -4500,6 +4501,14 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold, */ @implementation GSMimeDocument ++ (void) setText7bitBase64: (BOOL)aFlag +{ + if (YES == aFlag) + text7bitEncoding = @"base64"; + else + text7bitEncoding = @"quoted-printable"; +} + /* * Examine xml data to find out the characterset needed to convert from * binary data to an NSString object. @@ -5776,7 +5785,7 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold, if (e != NSASCIIStringEncoding && e != NSUTF7StringEncoding) #endif { - v = @"quoted-printable"; + v = text7bitEncoding; } else { @@ -6686,7 +6695,7 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold, */ if (YES == want7Bit) { - encoding = @"quoted-printable"; + encoding = text7bitEncoding; } enc = [self setHeader: @"Content-Transfer-Encoding" value: encoding diff --git a/Source/Additions/NSObject+GNUstepBase.m b/Source/Additions/NSObject+GNUstepBase.m index 71d5e30a4..143436dbe 100644 --- a/Source/Additions/NSObject+GNUstepBase.m +++ b/Source/Additions/NSObject+GNUstepBase.m @@ -145,6 +145,20 @@ struct exitLink { static struct exitLink *exited = 0; static BOOL enabled = NO; static BOOL shouldCleanUp = NO; +static NSLock *exitLock = nil; + +static inline void setup() +{ + if (nil == exitLock) + { + [gnustep_global_lock lock]; + if (nil == exitLock) + { + exitLock = [NSLock new]; + } + [gnustep_global_lock unlock]; + } +} static void handleExit() @@ -197,10 +211,11 @@ handleExit() l->at = anAddress; l->obj = [*anAddress retain]; l->sel = 0; - [gnustep_global_lock lock]; + setup(); + [exitLock lock]; l->next = exited; exited = l; - [gnustep_global_lock unlock]; + [exitLock unlock]; return l->obj; } @@ -212,10 +227,11 @@ handleExit() l->at = 0; l->obj = [anObject retain]; l->sel = 0; - [gnustep_global_lock lock]; + setup(); + [exitLock lock]; l->next = exited; exited = l; - [gnustep_global_lock unlock]; + [exitLock unlock]; return l->obj; } @@ -247,12 +263,13 @@ handleExit() return NO; // method not implemented in this class } - [gnustep_global_lock lock]; + setup(); + [exitLock lock]; for (l = exited; l != 0; l = l->next) { if (l->obj == self && sel_isEqual(l->sel, sel)) { - [gnustep_global_lock unlock]; + [exitLock unlock]; return NO; // Already registered } } @@ -267,7 +284,7 @@ handleExit() atexit(handleExit); enabled = YES; } - [gnustep_global_lock unlock]; + [exitLock unlock]; return YES; } @@ -275,13 +292,14 @@ handleExit() { if (YES == aFlag) { - [gnustep_global_lock lock]; + setup(); + [exitLock lock]; if (NO == enabled) { atexit(handleExit); enabled = YES; } - [gnustep_global_lock unlock]; + [exitLock unlock]; shouldCleanUp = YES; } else