Fix for bug #399

This commit is contained in:
rfm 2024-04-29 13:11:35 +01:00
parent 53b02bab91
commit a5beb6ab31
4 changed files with 55 additions and 16 deletions

View file

@ -1,3 +1,16 @@
2024-04-28 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSPrivate.h:
* Source/NSLock.m:
* Source/NSPathUtilities.m:
Fix for bug #399 ... the problem occurred becaause gnustep_global_lock
does not exist until +initialize is called on NSObject so in the path
utilities function the -lock message as sent to nil and the -unlock
message as sent to the lock.
The change adds a new GSPrivateGlobalLock() function to reliably return
a recursive lock, and alters the NSPathUtilities code to use it instead
of gnustep_global_lock (we should probably do that elsewhere too).
2024-04-15 Frederik Seiffert <frederik@algoriddim.com>
* Source/NSObject.m: add +[NSObject _TrivialAllocInit] to enable

View file

@ -33,6 +33,7 @@
@class _GSMutableInsensitiveDictionary;
@class NSNotification;
@class NSRecursiveLock;
#if ( (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) ) && HAVE_VISIBILITY_ATTRIBUTE )
#define GS_ATTRIB_PRIVATE __attribute__ ((visibility("internal")))
@ -422,6 +423,13 @@ GSPrivateLoadModule(NSString *filename, FILE *errorStream,
void (*loadCallback)(Class, struct objc_category *),
void **header, NSString *debugFilename) GS_ATTRIB_PRIVATE;
/* Return a private global recursive lock for protecting internal
* data structures before aother locks have been initialised.
* Implemented in NSLock.m
*/
NSRecursiveLock *
GSPrivateGlobalLock() GS_ATTRIB_PRIVATE;
/* Get the native C-string encoding as used by locale specific code in the
* operating system. This may differ from the default C-string encoding
* if the latter has been set via an environment variable.

View file

@ -43,7 +43,6 @@
#import "Foundation/NSLock.h"
#import "Foundation/NSException.h"
#import "Foundation/NSThread.h"
// #import "Foundation/NSUserDefaults.h"
#define class_createInstance(C,E) NSAllocateObject(C,E,NSDefaultMallocZone())
@ -907,6 +906,26 @@ MUNLOCK
}
@end
/* Return a global recursive lock
*/
NSRecursiveLock *
GSPrivateGlobalLock()
{
static NSRecursiveLock *lock = nil;
if (nil == lock)
{
static gs_mutex_t lockLock = GS_MUTEX_INIT_STATIC;
GS_MUTEX_LOCK(lockLock);
if (nil == lock)
{
lock = [GSUntracedRecursiveLock new];
}
GS_MUTEX_UNLOCK(lockLock);
}
return lock;
}
/*
* Pthread-like locking primitives using Windows SRWLock. Provides

View file

@ -83,7 +83,6 @@ NSMutableDictionary* GNUstepConfig(NSDictionary *newConfig);
void GNUstepUserConfig(NSMutableDictionary *config, NSString *userName);
/* The global configuration file. The real value is read from config.h */
#ifndef GNUSTEP_TARGET_CONFIG_FILE
# define GNUSTEP_TARGET_CONFIG_FILE "/etc/GNUstep/GNUstep.conf"
@ -909,7 +908,7 @@ GNUstepConfig(NSDictionary *newConfig)
NSMutableDictionary *conf = nil;
BOOL changedSystemConfig = NO;
[gnustep_global_lock lock];
[GSPrivateGlobalLock() lock];
if (NO == beenHere)
{
beenHere = YES;
@ -1063,14 +1062,14 @@ GNUstepConfig(NSDictionary *newConfig)
}
NS_HANDLER
{
[gnustep_global_lock unlock];
[GSPrivateGlobalLock() unlock];
config = nil;
DESTROY(conf);
[localException raise];
}
NS_ENDHANDLER
}
[gnustep_global_lock unlock];
[GSPrivateGlobalLock() unlock];
if (changedSystemConfig == YES)
{
@ -1141,7 +1140,7 @@ static void InitialisePathUtilities(void)
NSMutableDictionary *config;
static BOOL beenHere = NO;
[gnustep_global_lock lock];
[GSPrivateGlobalLock() lock];
if (NO == beenHere)
{
beenHere = YES;
@ -1196,12 +1195,12 @@ static void InitialisePathUtilities(void)
gnustepUserHome = [NSHomeDirectoryForUser(gnustepUserName) copy];
ExtractValuesFromConfig(config);
[gnustep_global_lock unlock];
[GSPrivateGlobalLock() unlock];
}
NS_HANDLER
{
/* unlock then re-raise the exception */
[gnustep_global_lock unlock];
[GSPrivateGlobalLock() unlock];
[localException raise];
}
NS_ENDHANDLER
@ -1607,7 +1606,7 @@ GSSetUserName(NSString *aName)
/*
* Release the memory
*/
[gnustep_global_lock lock];
[GSPrivateGlobalLock() lock];
ShutdownPathUtilities();
/*
@ -1618,7 +1617,7 @@ GSSetUserName(NSString *aName)
InitialisePathUtilities();
[NSUserDefaults resetStandardUserDefaults];
[gnustep_global_lock unlock];
[GSPrivateGlobalLock() unlock];
}
/**
@ -1691,11 +1690,11 @@ NSUserName(void)
#if defined(HAVE_GETPWUID)
struct passwd *pwent;
[gnustep_global_lock lock];
[GSPrivateGlobalLock() lock];
pwent = getpwuid (uid);
strncpy(buf, pwent->pw_name, sizeof(buf) - 1);
buf[sizeof(buf) - 1] = '\0';
[gnustep_global_lock unlock];
[GSPrivateGlobalLock() unlock];
loginName = buf;
#endif /* HAVE_GETPWUID */
#endif /* HAVE_GETPWUID_R */
@ -1756,13 +1755,13 @@ NSHomeDirectoryForUser(NSString *loginName)
#if defined(HAVE_GETPWNAM)
struct passwd *pw;
[gnustep_global_lock lock];
[GSPrivateGlobalLock() lock];
pw = getpwnam ([loginName cString]);
if (pw != 0 && pw->pw_dir != 0 && pw->pw_dir[0] != '\0')
{
s = [NSString stringWithUTF8String: pw->pw_dir];
}
[gnustep_global_lock unlock];
[GSPrivateGlobalLock() unlock];
#endif
#endif
#else
@ -1862,13 +1861,13 @@ NSFullUserName(void)
#if defined(HAVE_PW_GECOS_IN_PASSWD)
struct passwd *pw;
[gnustep_global_lock lock];
[GSPrivateGlobalLock() lock];
pw = getpwnam([userName cString]);
if (pw->pw_gecos)
{
userName = [NSString stringWithUTF8String: pw->pw_gecos];
}
[gnustep_global_lock lock];
[GSPrivateGlobalLock() unlock];
#endif /* HAVE_PW_GECOS_IN_PASSWD */
#endif /* HAVE_GETPWNAM */
#endif /* HAVE_GETPWNAM_R */