From 241e2a47cad07fafc4c2f62526b7289dec63b704 Mon Sep 17 00:00:00 2001 From: rfm Date: Thu, 30 May 2024 10:40:52 +0100 Subject: [PATCH] locking updates (fine grained locking rather than global lock) --- ChangeLog | 30 +++ Headers/Foundation/NSObject.h | 4 - Headers/GNUstepBase/GSLock.h | 71 ------ Headers/GNUstepBase/NSLock+GNUstepBase.h | 126 ---------- Source/Additions/GNUmakefile | 2 - Source/Additions/GSLock.m | 305 ----------------------- Source/Additions/NSError+GNUstepBase.m | 4 +- Source/Additions/NSLock+GNUstepBase.m | 100 -------- Source/Additions/NSObject+GNUstepBase.m | 7 +- Source/Additions/Unicode.m | 4 +- Source/DocMakefile | 2 - Source/GSLocale.m | 9 +- Source/NSDistributedNotificationCenter.m | 130 +++++----- Source/NSFileManager.m | 25 +- Source/NSHTTPCookieStorage.m | 6 +- Source/NSKeyValueObserving.m | 7 +- Source/NSLog.m | 7 +- Source/NSObject.m | 19 +- Source/NSPortNameServer.m | 7 +- Source/NSTask.m | 7 +- Source/NSThread.m | 11 +- Source/NSURLCache.m | 11 +- Source/NSURLCredentialStorage.m | 7 +- Source/ObjectiveC2/properties.m | 7 +- 24 files changed, 176 insertions(+), 732 deletions(-) delete mode 100644 Headers/GNUstepBase/GSLock.h delete mode 100644 Headers/GNUstepBase/NSLock+GNUstepBase.h delete mode 100644 Source/Additions/GSLock.m delete mode 100644 Source/Additions/NSLock+GNUstepBase.m diff --git a/ChangeLog b/ChangeLog index 1179cdbbb..4491259a3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +2024-04-30 Richard Frith-Macdonald + + * Headers/Foundation/NSObject.h: + * Headers/GNUstepBase/GSLock.h: + * Headers/GNUstepBase/NSLock+GNUstepBase.h: + * Source/Additions/GNUmakefile: + * Source/Additions/GSLock.m: + * Source/Additions/NSError+GNUstepBase.m: + * Source/Additions/NSLock+GNUstepBase.m: + * Source/Additions/NSObject+GNUstepBase.m: + * Source/Additions/Unicode.m: + * Source/DocMakefile: + * Source/GSLocale.m: + * Source/NSDistributedNotificationCenter.m: + * Source/NSFileManager.m: + * Source/NSHTTPCookieStorage.m: + * Source/NSKeyValueObserving.m: + * Source/NSLog.m: + * Source/NSObject.m: + * Source/NSPortNameServer.m: + * Source/NSTask.m: + * Source/NSThread.m: + * Source/NSURLCache.m: + * Source/NSURLCredentialStorage.m: + * Source/ObjectiveC2/properties.m: + Remove deprecated locking code. Use lightweight and more fine-grained + locking for simple cases protecting short regions. Retain a global + lock for more complex siutations where there is a significant chance of + deadlock. + 2024-04-26 Richard Frith-Macdonald * ChangeLog: Update for new release diff --git a/Headers/Foundation/NSObject.h b/Headers/Foundation/NSObject.h index 680814c25..97f03ea0b 100644 --- a/Headers/Foundation/NSObject.h +++ b/Headers/Foundation/NSObject.h @@ -502,10 +502,6 @@ NSIncrementExtraRefCount(id anObject); #if OS_API_VERSION(GS_API_NONE, GS_API_NONE) -/** DEPRECATED to be removed in next release. - */ -GS_EXPORT NSRecursiveLock *gnustep_global_lock; - @interface NSObject (NEXTSTEP) - (id) error:(const char *)aString, ...; /* - (const char *) name; diff --git a/Headers/GNUstepBase/GSLock.h b/Headers/GNUstepBase/GSLock.h deleted file mode 100644 index 653ef1130..000000000 --- a/Headers/GNUstepBase/GSLock.h +++ /dev/null @@ -1,71 +0,0 @@ -/** Some extra locking classes - - Copyright (C) 2003 Free Software Foundation, Inc. - - Written by: Richard Frith-Macdonald - - This file is part of the GNUstep Base Library. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02111 USA. - - AutogsdocSource: Additions/GSLock.m - -*/ - -#ifndef INCLUDED_GS_LOCK_H -#define INCLUDED_GS_LOCK_H - -#ifndef NeXT_Foundation_LIBRARY -#import -#else -#import -#endif - -#import "GNUstepBase/GSObjCRuntime.h" - -#if defined(__cplusplus) -extern "C" { -#endif - -@class NSNotification; - -/** DEPRECATED ... to be removed in next release - */ -GS_EXPORT_CLASS -@interface GSLazyLock : NSLock -{ - int locked; -} -- (void) _becomeThreaded: (NSNotification*)n; -@end - -GS_EXPORT_CLASS -@interface GSLazyRecursiveLock : NSRecursiveLock -{ - int counter; -} -- (void) _becomeThreaded: (NSNotification*)n; -@end - -/** DEPRECATED ... to be removed in next release - */ -GS_EXPORT NSRecursiveLock *gnustep_global_lock; - -#if defined(__cplusplus) -} -#endif - -#endif /* INCLUDED_GS_LOCK_H */ diff --git a/Headers/GNUstepBase/NSLock+GNUstepBase.h b/Headers/GNUstepBase/NSLock+GNUstepBase.h deleted file mode 100644 index 081279d74..000000000 --- a/Headers/GNUstepBase/NSLock+GNUstepBase.h +++ /dev/null @@ -1,126 +0,0 @@ -/** Declaration of extension methods for base additions - - Copyright (C) 2003-2010 Free Software Foundation, Inc. - - Written by: Richard Frith-Macdonald - and: Adam Fedor - - This file is part of the GNUstep Base Library. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02111 USA. - -*/ - -#ifndef INCLUDED_NSLock_GNUstepBase_h -#define INCLUDED_NSLock_GNUstepBase_h - -#import -#import - -#if defined(__cplusplus) -extern "C" { -#endif - -#if OS_API_VERSION(GS_API_NONE,GS_API_LATEST) - -/** - * Returns IDENT which will be initialized - * to an instance of a CLASSNAME in a thread safe manner. - * If IDENT has been previously initialized - * this macro merely returns IDENT. - * IDENT is considered uninitialized, if it contains nil. - * CLASSNAME must be either NSLock, NSRecursiveLock or one - * of their subclasses. - * See [NSLock(GNUstepBase)+newLockAt:] for details. - * This macro is intended for code that cannot insure - * that a lock can be initialized in thread safe manner otherwise. - * - * NSLock *my_lock = nil; - * - * void function (void) - * { - * [GS_INITIALIZED_LOCK(my_lock, NSLock) lock]; - * do_work (); - * [my_lock unlock]; - * } - * - * - */ -#define GS_INITIALIZED_LOCK(IDENT,CLASSNAME) \ - (IDENT != nil ? (id)IDENT : (id)[CLASSNAME newLockAt: &IDENT]) - -@interface NSLock (GNUstepBase) -/** - * Initializes the id pointed to by location - * with a new instance of the receiver's class - * in a thread safe manner, unless - * it has been previously initialized. - * Returns the contents pointed to by location. - * The location is considered unintialized if it contains nil. - *
- * This method is used in the GS_INITIALIZED_LOCK macro - * to initialize lock variables when it cannot be insured - * that they can be initialized in a thread safe environment. - * - * NSLock *my_lock = nil; - * - * void function (void) - * { - * [GS_INITIALIZED_LOCK(my_lock, NSLock) lock]; - * do_work (); - * [my_lock unlock]; - * } - * - * - */ -+ (id) newLockAt: (id *)location; -@end - -@interface NSRecursiveLock (GNUstepBase) -/** - * Initializes the id pointed to by location - * with a new instance of the receiver's class - * in a thread safe manner, unless - * it has been previously initialized. - * Returns the contents pointed to by location. - * The location is considered unintialized if it contains nil. - *
- * This method is used in the GS_INITIALIZED_LOCK macro - * to initialize lock variables when it cannot be insured - * that they can be initialized in a thread safe environment. - * - * NSLock *my_lock = nil; - * - * void function (void) - * { - * [GS_INITIALIZED_LOCK(my_lock, NSLock) lock]; - * do_work (); - * [my_lock unlock]; - * } - * - * - */ -+ (id) newLockAt: (id *)location; -@end - -#endif /* OS_API_VERSION */ - -#if defined(__cplusplus) -} -#endif - -#endif /* INCLUDED_NSLock_GNUstepBase_h */ - diff --git a/Source/Additions/GNUmakefile b/Source/Additions/GNUmakefile index 370322ea6..25a64653c 100644 --- a/Source/Additions/GNUmakefile +++ b/Source/Additions/GNUmakefile @@ -39,7 +39,6 @@ Additions_OBJC_FILES =\ GCObject.m \ GCArray.m \ GCDictionary.m \ - GSLock.m \ GSMime.m \ GSXML.m \ GSFunctions.m \ @@ -53,7 +52,6 @@ Additions_OBJC_FILES =\ NSError+GNUstepBase.m \ NSHashTable+GNUstepBase.m \ NSFileHandle+GNUstepBase.m \ - NSLock+GNUstepBase.m \ NSMutableString+GNUstepBase.m \ NSNumber+GNUstepBase.m \ NSObject+GNUstepBase.m \ diff --git a/Source/Additions/GSLock.m b/Source/Additions/GSLock.m deleted file mode 100644 index 6c7efd009..000000000 --- a/Source/Additions/GSLock.m +++ /dev/null @@ -1,305 +0,0 @@ -/** Implementation for GSLock - - Copyright (C) 2003 Free Software Foundation, Inc. - - Written by: Richard Frith-Macdonald - Date: October 2003 - - This file is part of the GNUstep Base Library. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02111 USA. -*/ - -#import "common.h" -#define EXPOSE_GSLock_IVARS 1 -#import "Foundation/NSException.h" -#import "Foundation/NSLock.h" -#import "Foundation/NSNotification.h" -#import "Foundation/NSThread.h" -#import "GNUstepBase/GSLock.h" - -/** - * This implements a class which, when used in single-threaded mode, - * acts like a lock while avoiding the overheads of actually using - * a real lock. However, when the programm in which the class is - * used becomes multi-threaded, all instances of this class transform - * themselves into real locks in the correct state (locked/unlocked) - * corresponding to whether the lazy lock was locked or not at the - * point where the program became multi threadeed.
- * Use of this class allows you to write thread-safe code which avoids - * locking inefficiencies when used in a single threaded application, - * without having to worry about dealing with the issue yourself. - */ -@implementation GSLazyLock - -/** - * Do not use this method ... it is used internally to handle the transition - * from a single threaded system to a multi threaded one. - */ -- (void) _becomeThreaded: (NSNotification*)n -{ - [[NSNotificationCenter defaultCenter] removeObserver: self]; - object_setClass(self, [NSLock class]); - if (locked == YES) - { - if ([self tryLock] == NO) - { - [NSException raise: NSInternalInconsistencyException - format: @"Failed to lock mutex"]; - } - } - /* - * While we have changed 'isa', it's possible someone might have - * cached our old method implementations, so we set the 'locked' - * ivar to a value to tell the old method implementations to use - * the superclass implementatins. - */ - locked = -1; -} - -- (void) dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver: self]; - [super dealloc]; -} - -- (id) init -{ - self = [super init]; - - if ([NSThread isMultiThreaded] == YES) - { - DESTROY(self); - return (GSLazyLock*)[NSLock new]; - } - else if (self != nil) - { - locked = NO; - [[NSNotificationCenter defaultCenter] - addObserver: self - selector: @selector(_becomeThreaded:) - name: NSWillBecomeMultiThreadedNotification - object: nil]; - } - return self; -} - -- (void) lock -{ - if (locked == NO) - { - locked = YES; - } - else if (locked == YES) - { - [NSException raise: NSGenericException - format: @"lock: when already locked"]; - } - else - { - [super lock]; - } -} - -- (BOOL) lockBeforeDate: (NSDate*)limit -{ - BOOL result; - - if (locked == NO) - { - result = YES; - } - else if (locked == YES) - { - result = NO; - [NSException raise: NSGenericException - format: @"lock: when already locked"]; - } - else - { - result = [super lockBeforeDate: limit]; - } - return result; -} - -- (BOOL) tryLock -{ - if (locked == NO) - { - locked = YES; - return YES; - } - else if (locked == YES) - { - return NO; - } - else - { - return [super tryLock]; - } -} - -- (void) unlock -{ - if (locked == YES) - { - locked = NO; - } - else if (locked == NO) - { - [NSException raise: NSGenericException - format: @"unlock: when already unlocked"]; - } - else - { - [super unlock]; - } -} - -@end - - - -/** - * This implements a class which, when used in single-threaded mode, - * acts like a recursive lock while avoiding the overheads of using - * a real lock. However, when the programm in which the class is - * used becomes multi-threaded, all instances of this class transform - * themselves into real locks in the correct state (locked/unlocked) - * corresponding to whether the lazy recursive lock was locked or not - * at the point where the program became multi threadeed.
- * Use of this class allows you to write thread-safe code which avoids - * locking inefficiencies when used in a single threaded application, - * without having to worry about dealing with the issue yourself. - */ -@implementation GSLazyRecursiveLock - -/** - * Do not use this method ... it is used internally to handle the transition - * from a single threaded system to a multi threaded one. - */ -- (void) _becomeThreaded: (NSNotification*)n -{ - [[NSNotificationCenter defaultCenter] removeObserver: self]; - object_setClass(self, [NSRecursiveLock class]); - while (counter-- > 0) - { - if ([self tryLock] == NO) - { - [NSException raise: NSInternalInconsistencyException - format: @"Failed to lock mutex"]; - } - } - /* - * While we have changed 'isa', it's possible someone might have - * cached our old method implementations, so we set the 'locked' - * ivar to a value to tell the old method implementations to use - * the superclass implementatins. - */ - counter = -1; -} - -- (void) dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver: self]; - [super dealloc]; -} - -- (id) init -{ - self = [super init]; - - if ([NSThread isMultiThreaded] == YES) - { - DESTROY(self); - return (GSLazyRecursiveLock*)[NSRecursiveLock new]; - } - else - { - if (self != nil) - { - [[NSNotificationCenter defaultCenter] - addObserver: self - selector: @selector(_becomeThreaded:) - name: NSWillBecomeMultiThreadedNotification - object: nil]; - } - } - return self; -} - -- (void) lock -{ - if (counter >= 0) - { - counter++; - } - else - { - [super lock]; - } -} - -- (BOOL) lockBeforeDate: (NSDate*)limit -{ - if (counter >= 0) - { - counter++; - return YES; - } - else - { - return [super lockBeforeDate: limit]; - } -} - -- (BOOL) tryLock -{ - if (counter >= 0) - { - counter++; - return YES; - } - else - { - return [super tryLock]; - } -} - -- (void) unlock -{ - if (counter > 0) - { - counter--; - } - else if (counter == 0) - { - [NSException raise: NSGenericException - format: @"unlock: failed to unlock mutex"]; - } - else - { - [super unlock]; - } -} - -@end - -/* Global lock to be used by classes when operating on any global - data that invoke other methods which also access global; thus, - creating the potential for deadlock. */ -NSRecursiveLock *gnustep_global_lock = nil; - diff --git a/Source/Additions/NSError+GNUstepBase.m b/Source/Additions/NSError+GNUstepBase.m index 02cbac0cd..efbd7433c 100644 --- a/Source/Additions/NSError+GNUstepBase.m +++ b/Source/Additions/NSError+GNUstepBase.m @@ -48,7 +48,7 @@ strerror_r(int eno, char *buf, int len) const char *ptr; int result; - [gnustep_global_lock lock]; + [GSPrivateGlobalLock() lock]; ptr = strerror(eno); if (ptr == 0) { @@ -61,7 +61,7 @@ strerror_r(int eno, char *buf, int len) result = 0; } buf[len - 1] = '\0'; - [gnustep_global_lock unlock]; + [GSPrivateGlobalLock() unlock]; return result; } #else diff --git a/Source/Additions/NSLock+GNUstepBase.m b/Source/Additions/NSLock+GNUstepBase.m deleted file mode 100644 index e501d4b37..000000000 --- a/Source/Additions/NSLock+GNUstepBase.m +++ /dev/null @@ -1,100 +0,0 @@ -/* Implementation of extension methods to base additions - - Copyright (C) 2010 Free Software Foundation, Inc. - - Written by: Richard Frith-Macdonald - - This file is part of the GNUstep Base Library. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02111 USA. - -*/ -#import "common.h" -#import "Foundation/NSException.h" -#import "GNUstepBase/NSLock+GNUstepBase.h" -#import "GNUstepBase/GSLock.h" - -/** - * GNUstep specific (non-standard) additions to the NSLock class. - */ - -static GSLazyRecursiveLock *local_lock = nil; - -/* This class only exists to provide a thread safe mechanism to - initialize local_lock as +initialize is called under a lock in ObjC - runtimes. User code should resort to GS_INITIALIZED_LOCK(), which - uses the +newLockAt: extension. */ - -@interface _GSLockInitializer : NSObject -@end -@implementation _GSLockInitializer -+ (void) initialize -{ - if (local_lock == nil) - { - /* As we do not know whether creating custom locks may - implicitly create other locks, we use a recursive lock. */ - local_lock = [GSLazyRecursiveLock new]; - } -} - -@end - -static inline id -newLockAt(Class self, SEL _cmd, id *location) -{ - if (location == 0) - { - [NSException raise: NSInvalidArgumentException - format: @"'%@' called with nil location", - NSStringFromSelector(_cmd)]; - } - - if (*location == nil) - { - if (local_lock == nil) - { - [_GSLockInitializer class]; - } - - [local_lock lock]; - - if (*location == nil) - { - *location = [[(id)self alloc] init]; - } - - [local_lock unlock]; - } - - return *location; -} - - -@implementation NSLock (GNUstepBase) -+ (id) newLockAt: (id *)location -{ - return newLockAt(self, _cmd, location); -} -@end - -@implementation NSRecursiveLock (GNUstepBase) -+ (id) newLockAt: (id *)location -{ - return newLockAt(self, _cmd, location); -} -@end - diff --git a/Source/Additions/NSObject+GNUstepBase.m b/Source/Additions/NSObject+GNUstepBase.m index cfeb71778..da286f1fc 100644 --- a/Source/Additions/NSObject+GNUstepBase.m +++ b/Source/Additions/NSObject+GNUstepBase.m @@ -23,6 +23,7 @@ */ #import "common.h" +#import "GSPThread.h" #import "Foundation/NSArray.h" #import "Foundation/NSException.h" #import "Foundation/NSHashTable.h" @@ -162,12 +163,14 @@ static inline void setup() { if (nil == exitLock) { - [gnustep_global_lock lock]; + static gs_mutex_t setupLock = GS_MUTEX_INIT_STATIC; + + GS_MUTEX_LOCK(setupLock); if (nil == exitLock) { exitLock = [NSLock new]; } - [gnustep_global_lock unlock]; + GS_MUTEX_UNLOCK(setupLock); } } diff --git a/Source/Additions/Unicode.m b/Source/Additions/Unicode.m index 7fe858746..86530a023 100644 --- a/Source/Additions/Unicode.m +++ b/Source/Additions/Unicode.m @@ -3100,7 +3100,7 @@ GSPrivateNativeCStringEncoding() char *old; /* Take it from the system locale information. */ - [gnustep_global_lock lock]; + [GSPrivateGlobalLock() lock]; /* Initialise locale system by setting current locale from * environment and then resetting it. Must be done before * any call to nl_langinfo() @@ -3111,7 +3111,7 @@ GSPrivateNativeCStringEncoding() } strncpy(encbuf, nl_langinfo(CODESET), sizeof(encbuf)-1); encbuf[sizeof(encbuf)-1] = '\0'; - [gnustep_global_lock unlock]; + [GSPrivateGlobalLock() unlock]; #else encbuf[0] = '\0'; #endif diff --git a/Source/DocMakefile b/Source/DocMakefile index 57db0f542..666001619 100644 --- a/Source/DocMakefile +++ b/Source/DocMakefile @@ -215,7 +215,6 @@ GSUnion.h \ GSIArray.h \ GSIMap.h \ GSLocale.h \ -GSLock.h \ GSFunctions.h \ GSMime.h \ GSTLS.h \ @@ -227,7 +226,6 @@ NSCalendarDate+GNUstepBase.h \ NSData+GNUstepBase.h \ NSDebug+GNUstepBase.h \ NSFileHandle+GNUstepBase.h \ -NSLock+GNUstepBase.h \ NSMutableString+GNUstepBase.h \ NSNumber+GNUstepBase.h \ NSObject+GNUstepBase.h \ diff --git a/Source/GSLocale.m b/Source/GSLocale.m index 9a58364a8..bfe8848f5 100644 --- a/Source/GSLocale.m +++ b/Source/GSLocale.m @@ -23,6 +23,7 @@ Boston, MA 02110 USA. */ #import "common.h" +#import "GSPrivate.h" #import "GNUstepBase/GSLocale.h" #import "Foundation/NSDictionary.h" #import "Foundation/NSArray.h" @@ -109,7 +110,7 @@ GSDomainFromDefaultLocale(void) /* Protect locale access with locks to prevent multiple threads using * it and interfering with the buffer. */ - [gnustep_global_lock lock]; + [GSPrivateGlobalLock() lock]; /** * Set the current locale to the system default, and backup @@ -231,7 +232,7 @@ GSDomainFromDefaultLocale(void) */ privateSetLocale(LC_ALL, backupLocale); - [gnustep_global_lock unlock]; + [GSPrivateGlobalLock() unlock]; return saved; } @@ -329,14 +330,14 @@ NSString *GSDefaultLanguageLocale() #ifdef LC_MESSAGES NSString *backup; - [gnustep_global_lock lock]; + [GSPrivateGlobalLock() lock]; backup = privateSetLocale(LC_ALL, nil); privateSetLocale(LC_ALL, @""); locale = privateSetLocale(LC_MESSAGES, nil); privateSetLocale(LC_ALL, backup); - [gnustep_global_lock unlock]; + [GSPrivateGlobalLock() unlock]; #endif #endif diff --git a/Source/NSDistributedNotificationCenter.m b/Source/NSDistributedNotificationCenter.m index b95560375..4677cd397 100644 --- a/Source/NSDistributedNotificationCenter.m +++ b/Source/NSDistributedNotificationCenter.m @@ -26,6 +26,7 @@ */ #import "common.h" + #define EXPOSE_NSDistributedNotificationCenter_IVARS 1 #import "Foundation/NSConnection.h" #import "Foundation/NSDistantObject.h" @@ -44,6 +45,7 @@ #import "Foundation/NSPortNameServer.h" #import "Foundation/NSThread.h" #import "../Tools/gdnc.h" +#import "GSPThread.h" @interface NSDistributedNotificationCenter (Private) @@ -103,6 +105,8 @@ static NSDistributedNotificationCenter *locCenter = nil; static NSDistributedNotificationCenter *pubCenter = nil; static NSDistributedNotificationCenter *netCenter = nil; +static gs_mutex_t classLock = GS_MUTEX_INIT_STATIC; + + (id) allocWithZone: (NSZone*)z { @@ -140,28 +144,28 @@ static NSDistributedNotificationCenter *netCenter = nil; { if (locCenter == nil) { - [gnustep_global_lock lock]; - if (locCenter == nil) - { - NS_DURING - { - NSDistributedNotificationCenter *tmp; + GS_MUTEX_LOCK(classLock); + if (locCenter == nil) + { + NS_DURING + { + NSDistributedNotificationCenter *tmp; - tmp = (NSDistributedNotificationCenter*) - NSAllocateObject(self, 0, NSDefaultMallocZone()); - tmp->_centerLock = [NSRecursiveLock new]; - tmp->_type = RETAIN(NSLocalNotificationCenterType); - locCenter = [NSObject leak: tmp]; - [tmp release]; - } - NS_HANDLER - { - [gnustep_global_lock unlock]; - [localException raise]; - } - NS_ENDHANDLER - } - [gnustep_global_lock unlock]; + tmp = (NSDistributedNotificationCenter*) + NSAllocateObject(self, 0, NSDefaultMallocZone()); + tmp->_centerLock = [NSRecursiveLock new]; + tmp->_type = RETAIN(NSLocalNotificationCenterType); + locCenter = [NSObject leak: tmp]; + [tmp release]; + } + NS_HANDLER + { + GS_MUTEX_UNLOCK(classLock); + [localException raise]; + } + NS_ENDHANDLER + } + GS_MUTEX_UNLOCK(classLock); } return locCenter; } @@ -169,28 +173,28 @@ static NSDistributedNotificationCenter *netCenter = nil; { if (pubCenter == nil) { - [gnustep_global_lock lock]; - if (pubCenter == nil) - { - NS_DURING - { - NSDistributedNotificationCenter *tmp; + GS_MUTEX_LOCK(classLock); + if (pubCenter == nil) + { + NS_DURING + { + NSDistributedNotificationCenter *tmp; - tmp = (NSDistributedNotificationCenter*) - NSAllocateObject(self, 0, NSDefaultMallocZone()); - tmp->_centerLock = [NSRecursiveLock new]; - tmp->_type = RETAIN(GSPublicNotificationCenterType); - pubCenter = [NSObject leak: tmp]; - [tmp release]; - } - NS_HANDLER - { - [gnustep_global_lock unlock]; - [localException raise]; - } - NS_ENDHANDLER - } - [gnustep_global_lock unlock]; + tmp = (NSDistributedNotificationCenter*) + NSAllocateObject(self, 0, NSDefaultMallocZone()); + tmp->_centerLock = [NSRecursiveLock new]; + tmp->_type = RETAIN(GSPublicNotificationCenterType); + pubCenter = [NSObject leak: tmp]; + [tmp release]; + } + NS_HANDLER + { + GS_MUTEX_UNLOCK(classLock); + [localException raise]; + } + NS_ENDHANDLER + } + GS_MUTEX_UNLOCK(classLock); } return pubCenter; } @@ -198,28 +202,28 @@ static NSDistributedNotificationCenter *netCenter = nil; { if (netCenter == nil) { - [gnustep_global_lock lock]; - if (netCenter == nil) - { - NS_DURING - { - NSDistributedNotificationCenter *tmp; + GS_MUTEX_LOCK(classLock); + if (netCenter == nil) + { + NS_DURING + { + NSDistributedNotificationCenter *tmp; - tmp = (NSDistributedNotificationCenter*) - NSAllocateObject(self, 0, NSDefaultMallocZone()); - tmp->_centerLock = [NSRecursiveLock new]; - tmp->_type = RETAIN(GSNetworkNotificationCenterType); - netCenter = [NSObject leak: tmp]; - [tmp release]; - } - NS_HANDLER - { - [gnustep_global_lock unlock]; - [localException raise]; - } - NS_ENDHANDLER - } - [gnustep_global_lock unlock]; + tmp = (NSDistributedNotificationCenter*) + NSAllocateObject(self, 0, NSDefaultMallocZone()); + tmp->_centerLock = [NSRecursiveLock new]; + tmp->_type = RETAIN(GSNetworkNotificationCenterType); + netCenter = [NSObject leak: tmp]; + [tmp release]; + } + NS_HANDLER + { + GS_MUTEX_UNLOCK(classLock); + [localException raise]; + } + NS_ENDHANDLER + } + GS_MUTEX_UNLOCK(classLock); } return netCenter; } diff --git a/Source/NSFileManager.m b/Source/NSFileManager.m index 79daea2f7..1ec16a258 100644 --- a/Source/NSFileManager.m +++ b/Source/NSFileManager.m @@ -348,8 +348,9 @@ exitedThread(void *lastErrorPtr) // Getting the default manager -static NSFileManager* defaultManager = nil; +static NSFileManager *defaultManager = nil; static NSStringEncoding defaultEncoding; +static gs_mutex_t classLock = GS_MUTEX_INIT_STATIC; + (NSFileManager*) defaultManager { @@ -357,17 +358,17 @@ static NSStringEncoding defaultEncoding; { NS_DURING { - [gnustep_global_lock lock]; + GS_MUTEX_LOCK(classLock); if (defaultManager == nil) { defaultManager = [[self alloc] init]; } - [gnustep_global_lock unlock]; + GS_MUTEX_UNLOCK(classLock); } NS_HANDLER { // unlock then re-raise the exception - [gnustep_global_lock unlock]; + GS_MUTEX_UNLOCK(classLock); [localException raise]; } NS_ENDHANDLER @@ -489,14 +490,14 @@ static NSStringEncoding defaultEncoding; #if defined(HAVE_GETPWNAM) struct passwd *pw; - [gnustep_global_lock lock]; + GS_MUTEX_LOCK(classLock); pw = getpwnam([str cStringUsingEncoding: defaultEncoding]); if (pw != 0) { ok = (chown(lpath, pw->pw_uid, -1) == 0); (void)chown(lpath, -1, pw->pw_gid); } - [gnustep_global_lock unlock]; + GS_MUTEX_UNLOCK(classLock); #endif #endif #endif @@ -553,14 +554,14 @@ static NSStringEncoding defaultEncoding; #ifdef HAVE_GETGRNAM struct group *gp; - [gnustep_global_lock lock]; + GS_MUTEX_LOCK(classLock); gp = getgrnam([str cStringUsingEncoding: defaultEncoding]); if (gp) { if (chown(lpath, -1, gp->gr_gid) == 0) ok = YES; } - [gnustep_global_lock unlock]; + GS_MUTEX_UNLOCK(classLock); #endif #endif #endif @@ -3929,14 +3930,14 @@ static NSSet *fileKeys = nil; #if defined(HAVE_GETGRGID) struct group *gp; - [gnustep_global_lock lock]; + GS_MUTEX_LOCK(classLock); gp = getgrgid(statbuf.st_gid); if (gp != 0) { group = [NSString stringWithCString: gp->gr_name encoding: defaultEncoding]; } - [gnustep_global_lock unlock]; + GS_MUTEX_UNLOCK(classLock); #endif #endif #endif @@ -4096,14 +4097,14 @@ static NSSet *fileKeys = nil; #if defined(HAVE_GETPWUID) struct passwd *pw; - [gnustep_global_lock lock]; + GS_MUTEX_LOCK(classLock); pw = getpwuid(statbuf.st_uid); if (pw != 0) { owner = [NSString stringWithCString: pw->pw_name encoding: defaultEncoding]; } - [gnustep_global_lock unlock]; + GS_MUTEX_UNLOCK(classLock); #endif #endif #endif /* HAVE_PWD_H */ diff --git a/Source/NSHTTPCookieStorage.m b/Source/NSHTTPCookieStorage.m index a5a0be019..4b507e59e 100644 --- a/Source/NSHTTPCookieStorage.m +++ b/Source/NSHTTPCookieStorage.m @@ -24,6 +24,7 @@ #import "common.h" #define EXPOSE_NSHTTPCookieStorage_IVARS 1 +#import "GSPThread.h" #import "GSURLPrivate.h" #import "Foundation/NSSet.h" #import "Foundation/NSArray.h" @@ -50,6 +51,7 @@ typedef struct { @implementation NSHTTPCookieStorage static NSHTTPCookieStorage *storage = nil; +static gs_mutex_t classLock = GS_MUTEX_INIT_STATIC; + (id) allocWithZone: (NSZone*)z { @@ -60,7 +62,7 @@ static NSHTTPCookieStorage *storage = nil; { if (storage == nil) { - [gnustep_global_lock lock]; + GS_MUTEX_LOCK(classLock); if (storage == nil) { NSHTTPCookieStorage *o; @@ -72,7 +74,7 @@ static NSHTTPCookieStorage *storage = nil; [o init]; storage = o; } - [gnustep_global_lock unlock]; + GS_MUTEX_UNLOCK(classLock); } return storage; } diff --git a/Source/NSKeyValueObserving.m b/Source/NSKeyValueObserving.m index e80221ddd..3bc8666c1 100644 --- a/Source/NSKeyValueObserving.m +++ b/Source/NSKeyValueObserving.m @@ -43,6 +43,7 @@ #import "GNUstepBase/Unicode.h" #import "GNUstepBase/GSLock.h" #import "GSInvocation.h" +#import "GSPThread.h" #if defined(USE_LIBFFI) #import "cifframe.h" @@ -78,9 +79,11 @@ static id null; static inline void setup() { + static gs_mutex_t setupLock = GS_MUTEX_INIT_STATIC; + if (nil == kvoLock) { - [gnustep_global_lock lock]; + GS_MUTEX_LOCK(setupLock); if (nil == kvoLock) { kvoLock = [NSRecursiveLock new]; @@ -93,7 +96,7 @@ setup() NSOwnedPointerMapValueCallBacks, 128); baseClass = NSClassFromString(@"GSKVOBase"); } - [gnustep_global_lock unlock]; + GS_MUTEX_UNLOCK(setupLock); } } /* diff --git a/Source/NSLog.m b/Source/NSLog.m index 7734cce9f..ee3c5aea4 100644 --- a/Source/NSLog.m +++ b/Source/NSLog.m @@ -26,6 +26,7 @@ */ #import "common.h" +#import "GSPThread.h" #import "Foundation/NSDate.h" #import "Foundation/NSCalendarDate.h" #import "Foundation/NSTimeZone.h" @@ -101,14 +102,16 @@ GSLogLock() { if (myLock == nil) { - [gnustep_global_lock lock]; + static gs_mutex_t setupLock = GS_MUTEX_INIT_STATIC; + + GS_MUTEX_LOCK(setupLock); if (myLock == nil) { myLock = [NSRecursiveLock new]; lockImp = [myLock methodForSelector: @selector(lock)]; unlockImp = [myLock methodForSelector: @selector(unlock)]; } - [gnustep_global_lock unlock]; + GS_MUTEX_UNLOCK(setupLock); } return myLock; } diff --git a/Source/NSObject.m b/Source/NSObject.m index 3b7814a6f..61a51d339 100644 --- a/Source/NSObject.m +++ b/Source/NSObject.m @@ -636,7 +636,8 @@ static id objc_retain_fast_np_internal(id anObject) #endif /* GSATOMICREAD */ if (YES == tooFar) { - static NSHashTable *overrun = nil; + static NSHashTable *overrun = nil; + static gs_mutex_t countLock = GS_MUTEX_INIT_STATIC; /* We store this instance in a hash table so that we will only raise * an exception for it once (and can therefore expect to log the instance @@ -644,7 +645,7 @@ static id objc_retain_fast_np_internal(id anObject) * NB. The hash table does not retain the object, so the code in the * lock protected region below should be safe anyway. */ - [gnustep_global_lock lock]; + GS_MUTEX_LOCK(countLock); if (nil == overrun) { overrun = NSCreateHashTable(NSNonRetainedObjectHashCallBacks, 0); @@ -657,7 +658,7 @@ static id objc_retain_fast_np_internal(id anObject) { tooFar = NO; } - [gnustep_global_lock lock]; + GS_MUTEX_UNLOCK(countLock); if (YES == tooFar) { NSString *base; @@ -1042,13 +1043,6 @@ static id gs_weak_load(id obj) } #endif - /* Create the global lock. - * NB. Ths is one of the first things we do ... setting up a new lock - * must not call any other Objective-C classes and must not involve - * any use of the autorelease system. - */ - gnustep_global_lock = [GSUntracedRecursiveLock new]; - /* Behavior debugging ... enable with environment variable if needed. */ GSObjCBehaviorDebug(GSPrivateEnvironmentFlag("GNUSTEP_BEHAVIOR_DEBUG", @@ -1073,11 +1067,6 @@ static id gs_weak_load(id obj) */ NSConstantStringClass = [NSString constantStringClass]; - /* Now that the string class (and autorelease) is set up, we can set - * the name of the lock to a string value safely. - */ - [gnustep_global_lock setName: @"gnustep_global_lock"]; - /* Determine zombie management flags and set up a map to store * information about zombie objects. */ diff --git a/Source/NSPortNameServer.m b/Source/NSPortNameServer.m index ae76e4891..b66437281 100644 --- a/Source/NSPortNameServer.m +++ b/Source/NSPortNameServer.m @@ -26,6 +26,7 @@ */ #import "common.h" +#import "GSPThread.h" #import "Foundation/NSException.h" #import "Foundation/NSEnumerator.h" #import "Foundation/NSPort.h" @@ -74,7 +75,9 @@ if (nameServer == nil) { - [gnustep_global_lock lock]; + static gs_mutex_t classLock = GS_MUTEX_INIT_STATIC; + + GS_MUTEX_LOCK(classLock); if (nameServer == nil) { NSUserDefaults *defs = [NSUserDefaults standardUserDefaults]; @@ -91,7 +94,7 @@ } nameServer = RETAIN(o); } - [gnustep_global_lock unlock]; + GS_MUTEX_UNLOCK(classLock); } return nameServer; } diff --git a/Source/NSTask.m b/Source/NSTask.m index 431cb5539..58f6cbbfc 100644 --- a/Source/NSTask.m +++ b/Source/NSTask.m @@ -25,6 +25,7 @@ */ #import "common.h" +#import "GSPThread.h" #define EXPOSE_NSTask_IVARS 1 #import "Foundation/FoundationErrors.h" #import "Foundation/NSAutoreleasePool.h" @@ -250,7 +251,9 @@ pty_slave(const char* name) { if (self == [NSTask class]) { - [gnustep_global_lock lock]; + static gs_mutex_t classLock = GS_MUTEX_INIT_STATIC; + + GS_MUTEX_LOCK(classLock); if (tasksLock == nil) { tasksLock = [NSRecursiveLock new]; @@ -281,7 +284,7 @@ pty_slave(const char* name) NSObjectMapValueCallBacks, 0); [[NSObject leakAt: &activeTasks] release]; } - [gnustep_global_lock unlock]; + GS_MUTEX_UNLOCK(classLock); #ifndef _WIN32 signal(SIGCHLD, handleSignal); diff --git a/Source/NSThread.m b/Source/NSThread.m index f4952b3d4..3bee0bc6a 100644 --- a/Source/NSThread.m +++ b/Source/NSThread.m @@ -378,11 +378,12 @@ GSSleepUntilIntervalSinceReferenceDate(NSTimeInterval when) static NSArray * commonModes(void) { + static gs_mutex_t modesLock = GS_MUTEX_INIT_STATIC; static NSArray *modes = nil; if (modes == nil) { - [gnustep_global_lock lock]; + GS_MUTEX_LOCK(modesLock); if (modes == nil) { Class c = NSClassFromString(@"NSApplication"); @@ -398,7 +399,7 @@ commonModes(void) NSDefaultRunLoopMode, NSConnectionReplyMode, nil]; } } - [gnustep_global_lock unlock]; + GS_MUTEX_UNLOCK(modesLock); } return modes; } @@ -2094,12 +2095,14 @@ GSRunLoopInfoForThread(NSThread *aThread) } if (aThread->_runLoopInfo == nil) { - [gnustep_global_lock lock]; + static gs_mutex_t infoLock = GS_MUTEX_INIT_STATIC; + + GS_MUTEX_LOCK(infoLock); if (aThread->_runLoopInfo == nil) { aThread->_runLoopInfo = [GSRunLoopThreadInfo new]; } - [gnustep_global_lock unlock]; + GS_MUTEX_UNLOCK(infoLock); } info = aThread->_runLoopInfo; return info; diff --git a/Source/NSURLCache.m b/Source/NSURLCache.m index 01e40a23c..3be94331a 100644 --- a/Source/NSURLCache.m +++ b/Source/NSURLCache.m @@ -24,6 +24,8 @@ #import "common.h" +#import "GSPThread.h" + #if GS_HAVE_NSURLSESSION #import #endif @@ -46,6 +48,7 @@ typedef struct { static NSURLCache *shared = nil; +static gs_mutex_t cacheLock = GS_MUTEX_INIT_STATIC; @implementation NSURLCache @@ -62,9 +65,9 @@ static NSURLCache *shared = nil; + (void) setSharedURLCache: (NSURLCache *)cache { - [gnustep_global_lock lock]; + GS_MUTEX_LOCK(cacheLock); ASSIGN(shared, cache); - [gnustep_global_lock unlock]; + GS_MUTEX_UNLOCK(cacheLock); } - (void) dealloc @@ -82,7 +85,7 @@ static NSURLCache *shared = nil; { NSURLCache *c; - [gnustep_global_lock lock]; + GS_MUTEX_LOCK(cacheLock); if (shared == nil) { NSString *path = nil; @@ -95,7 +98,7 @@ static NSURLCache *shared = nil; } c = RETAIN(shared); - [gnustep_global_lock unlock]; + GS_MUTEX_UNLOCK(cacheLock); return AUTORELEASE(c); } diff --git a/Source/NSURLCredentialStorage.m b/Source/NSURLCredentialStorage.m index 13c4ad4ca..cd4d37036 100644 --- a/Source/NSURLCredentialStorage.m +++ b/Source/NSURLCredentialStorage.m @@ -23,6 +23,7 @@ */ #import "common.h" +#import "GSPThread.h" #define EXPOSE_NSURLCredentialStorage_IVARS 1 #import "GSURLPrivate.h" @@ -46,9 +47,11 @@ static NSURLCredentialStorage *storage = nil; + (NSURLCredentialStorage *) sharedCredentialStorage { + static gs_mutex_t classLock = GS_MUTEX_INIT_STATIC; + if (storage == nil) { - [gnustep_global_lock lock]; + GS_MUTEX_LOCK(classLock); if (storage == nil) { NSURLCredentialStorage *o; @@ -63,7 +66,7 @@ static NSURLCredentialStorage *storage = nil; = [NSMutableDictionary new]; storage = o; } - [gnustep_global_lock unlock]; + GS_MUTEX_UNLOCK(classLock); } return storage; } diff --git a/Source/ObjectiveC2/properties.m b/Source/ObjectiveC2/properties.m index 8fb84f968..fa9eb6f35 100644 --- a/Source/ObjectiveC2/properties.m +++ b/Source/ObjectiveC2/properties.m @@ -8,6 +8,7 @@ */ #import "Foundation/NSException.h" #import "Foundation/NSLock.h" +#import "GSPThread.h" static NSRecursiveLock *propertyLock = nil; static inline NSRecursiveLock* @@ -15,12 +16,14 @@ pLock() { if (propertyLock == nil) { - [gnustep_global_lock lock]; + static gs_mutex_t setupLock = GS_MUTEX_INIT_STATIC; + + GS_MUTEX_LOCK(setupLock); if (propertyLock == nil) { propertyLock = [NSRecursiveLock new]; } - [gnustep_global_lock unlock]; + GS_MUTEX_UNLOCK(setupLock); } return propertyLock; }