mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 09:04:13 +00:00
Free 'leaked' memory at exit.
This commit is contained in:
parent
bb57918f70
commit
1c7e81dee1
3 changed files with 105 additions and 39 deletions
|
@ -114,7 +114,23 @@ static SEL rlSel;
|
|||
defaultPlaceholderArray = nil;
|
||||
NSDeallocateObject(o);
|
||||
|
||||
DESTROY(placeholderMap);
|
||||
/* Deallocate all the placeholders in the map before destroying it.
|
||||
*/
|
||||
GS_MUTEX_LOCK(placeholderLock);
|
||||
if (placeholderMap)
|
||||
{
|
||||
NSMapEnumerator mEnum = NSEnumerateMapTable(placeholderMap);
|
||||
Class c;
|
||||
id o;
|
||||
|
||||
while (NSNextMapEnumeratorPair(&mEnum, (void *)&c, (void *)&o))
|
||||
{
|
||||
NSDeallocateObject(o);
|
||||
}
|
||||
NSEndMapTableEnumeration(&mEnum);
|
||||
DESTROY(placeholderMap);
|
||||
}
|
||||
GS_MUTEX_UNLOCK(placeholderLock);
|
||||
}
|
||||
|
||||
+ (void) initialize
|
||||
|
@ -176,7 +192,7 @@ static SEL rlSel;
|
|||
*/
|
||||
GS_MUTEX_LOCK(placeholderLock);
|
||||
obj = (id)NSMapGet(placeholderMap, (void*)z);
|
||||
if (obj == nil)
|
||||
if (obj == nil && NO == [NSObject isExiting])
|
||||
{
|
||||
/*
|
||||
* There is no placeholder object for this zone, so we
|
||||
|
|
|
@ -189,12 +189,12 @@ _NSToICUTZDisplayStyle(NSTimeZoneNameStyle style)
|
|||
static inline UCalendar *
|
||||
ICUCalendarSetup (NSTimeZone *tz, NSLocale *locale)
|
||||
{
|
||||
NSString *tzStr;
|
||||
int32_t tzLen;
|
||||
const char *cLocale;
|
||||
UChar tzName[BUFFER_SIZE];
|
||||
UCalendar *cal;
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
NSString *tzStr;
|
||||
int32_t tzLen;
|
||||
const char *cLocale;
|
||||
UChar tzName[BUFFER_SIZE];
|
||||
UCalendar *cal;
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
|
||||
tzStr = [tz name];
|
||||
if ((tzLen = [tzStr length]) > BUFFER_SIZE)
|
||||
|
@ -287,6 +287,9 @@ static NSMutableDictionary *abbreviationDictionary = nil;
|
|||
/* one-to-many abbreviation to time zone name dictionary. */
|
||||
static NSMutableDictionary *abbreviationMap = nil;
|
||||
|
||||
static NSArray *namesArray = nil;
|
||||
static NSArray *regionsArray = nil;
|
||||
|
||||
/* Lock for creating time zones. */
|
||||
static gs_mutex_t zone_mutex;
|
||||
|
||||
|
@ -991,7 +994,7 @@ static NSMapTable *absolutes = 0;
|
|||
NSAutoreleasePool *pool = [NSAutoreleasePool new];
|
||||
NSString *path;
|
||||
|
||||
path = _time_zone_path (ABBREV_DICT, @"plist");
|
||||
path = _time_zone_path(ABBREV_DICT, @"plist");
|
||||
if (path != nil)
|
||||
{
|
||||
/*
|
||||
|
@ -1195,8 +1198,6 @@ static NSMapTable *absolutes = 0;
|
|||
*/
|
||||
+ (NSArray*) knownTimeZoneNames
|
||||
{
|
||||
static NSArray *namesArray = nil;
|
||||
|
||||
/* We create the array only when we need it to reduce overhead. */
|
||||
if (namesArray != nil)
|
||||
{
|
||||
|
@ -1204,7 +1205,7 @@ static NSMapTable *absolutes = 0;
|
|||
}
|
||||
|
||||
GS_MUTEX_LOCK(zone_mutex);
|
||||
if (namesArray == nil)
|
||||
if (namesArray == nil && NO == [NSObject isExiting])
|
||||
{
|
||||
unsigned i;
|
||||
NSMutableArray *ma;
|
||||
|
@ -1284,14 +1285,33 @@ static NSMapTable *absolutes = 0;
|
|||
{
|
||||
id o;
|
||||
|
||||
/* Deallocate all the placeholders in the map before destroying it.
|
||||
*/
|
||||
GS_MUTEX_LOCK(zone_mutex);
|
||||
if (placeholderMap)
|
||||
{
|
||||
NSMapEnumerator mEnum = NSEnumerateMapTable(placeholderMap);
|
||||
Class c;
|
||||
id o;
|
||||
|
||||
while (NSNextMapEnumeratorPair(&mEnum, (void *)&c, (void *)&o))
|
||||
{
|
||||
NSDeallocateObject(o);
|
||||
}
|
||||
NSEndMapTableEnumeration(&mEnum);
|
||||
DESTROY(placeholderMap);
|
||||
}
|
||||
GS_MUTEX_UNLOCK(zone_mutex);
|
||||
|
||||
DESTROY(zoneDictionary);
|
||||
DESTROY(placeholderMap);
|
||||
DESTROY(localTimeZone);
|
||||
DESTROY(defaultTimeZone);
|
||||
DESTROY(systemTimeZone);
|
||||
DESTROY(abbreviationDictionary);
|
||||
DESTROY(abbreviationMap);
|
||||
DESTROY(absolutes);
|
||||
DESTROY(namesArray);
|
||||
DESTROY(regionsArray);
|
||||
|
||||
o = defaultPlaceholderTimeZone;
|
||||
defaultPlaceholderTimeZone = nil;
|
||||
|
@ -1653,7 +1673,8 @@ static NSMapTable *absolutes = 0;
|
|||
if (localZoneString != nil)
|
||||
{
|
||||
NSDebugLLog (@"NSTimeZone", @"Using zone %@", localZoneString);
|
||||
zone = [defaultPlaceholderTimeZone initWithName: localZoneString];
|
||||
zone = AUTORELEASE([defaultPlaceholderTimeZone
|
||||
initWithName: localZoneString]);
|
||||
if (zone == nil)
|
||||
{
|
||||
NSArray *possibleZoneNames;
|
||||
|
@ -1689,7 +1710,7 @@ static NSMapTable *absolutes = 0;
|
|||
&& [dflt contentsEqualAtPath: fileName
|
||||
andPath: SYSTEM_TIME_FILE])
|
||||
{
|
||||
zone = [[self timeZoneWithName: zoneName] retain];
|
||||
zone = [self timeZoneWithName: zoneName];
|
||||
|
||||
if (zone != nil)
|
||||
{
|
||||
|
@ -1737,7 +1758,7 @@ zoneName, LOCALDBKEY, LOCALDBKEY, zoneName);
|
|||
@"See '%@'\n"
|
||||
@"for the standard timezones such as 'GB-Eire' or 'America/Chicago'.\n",
|
||||
LOCALDBKEY, LOCALDBKEY, _time_zone_path (ZONES_DIR, nil));
|
||||
zone = [[self timeZoneWithAbbreviation: localZoneString] retain];
|
||||
zone = [self timeZoneWithAbbreviation: localZoneString];
|
||||
if (zone != nil)
|
||||
{
|
||||
NSInteger s;
|
||||
|
@ -1771,7 +1792,7 @@ localZoneString, [zone name], sign, s/3600, (s/60)%60);
|
|||
if (zone == nil)
|
||||
{
|
||||
NSLog(@"Using time zone with absolute offset 0.");
|
||||
zone = systemTimeZone;
|
||||
zone = [self timeZoneForSecondsFromGMT: 0];
|
||||
}
|
||||
ASSIGN(systemTimeZone, zone);
|
||||
}
|
||||
|
@ -1786,17 +1807,15 @@ localZoneString, [zone name], sign, s/3600, (s/60)%60);
|
|||
* Each element contains an array of NSStrings which are
|
||||
* the region names.
|
||||
*/
|
||||
+ (NSArray *)timeZoneArray
|
||||
+ (NSArray*) timeZoneArray
|
||||
{
|
||||
static NSArray *regionsArray = nil;
|
||||
|
||||
/* We create the array only when we need it to reduce overhead. */
|
||||
if (regionsArray != nil)
|
||||
{
|
||||
return regionsArray;
|
||||
}
|
||||
GS_MUTEX_LOCK(zone_mutex);
|
||||
if (regionsArray == nil)
|
||||
if (regionsArray == nil && NO == [NSObject isExiting])
|
||||
{
|
||||
NSAutoreleasePool *pool = [NSAutoreleasePool new];
|
||||
NSMutableArray *temp_array[24];
|
||||
|
@ -1838,9 +1857,9 @@ localZoneString, [zone name], sign, s/3600, (s/60)%60);
|
|||
newLineSet = [NSCharacterSet newlineCharacterSet];
|
||||
scanner = [NSScanner scannerWithString: contents];
|
||||
|
||||
while ([scanner scanInteger: &index] &&
|
||||
[scanner scanUpToCharactersFromSet: newLineSet
|
||||
intoString: &name])
|
||||
while ([scanner scanInteger: &index]
|
||||
&& [scanner scanUpToCharactersFromSet: newLineSet
|
||||
intoString: &name])
|
||||
{
|
||||
if (index < 0)
|
||||
index = 0;
|
||||
|
@ -1851,7 +1870,7 @@ localZoneString, [zone name], sign, s/3600, (s/60)%60);
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
NSString *zonedir = [NSTimeZone _getTimeZoneFile: @"WET"];
|
||||
|
||||
if (tzdir != nil)
|
||||
|
@ -2367,21 +2386,21 @@ localZoneString, [zone name], sign, s/3600, (s/60)%60);
|
|||
UCalendar *cal;
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
|
||||
cal = ICUCalendarSetup (self, locale);
|
||||
cal = ICUCalendarSetup(self, locale);
|
||||
if (cal == NULL)
|
||||
return nil;
|
||||
|
||||
cLocale = [[locale localeIdentifier] UTF8String];
|
||||
result = NSZoneMalloc ([self zone], BUFFER_SIZE * sizeof(UChar));
|
||||
len = ucal_getTimeZoneDisplayName (cal, _NSToICUTZDisplayStyle(style),
|
||||
result = NSZoneMalloc([self zone], BUFFER_SIZE * sizeof(UChar));
|
||||
len = ucal_getTimeZoneDisplayName(cal, _NSToICUTZDisplayStyle(style),
|
||||
cLocale, result, BUFFER_SIZE, &err);
|
||||
if (len > BUFFER_SIZE)
|
||||
{
|
||||
result = NSZoneRealloc ([self zone], result, len * sizeof(UChar));
|
||||
ucal_getTimeZoneDisplayName (cal, _NSToICUTZDisplayStyle(style),
|
||||
result = NSZoneRealloc([self zone], result, len * sizeof(UChar));
|
||||
ucal_getTimeZoneDisplayName(cal, _NSToICUTZDisplayStyle(style),
|
||||
cLocale, result, len, &err);
|
||||
}
|
||||
|
||||
ucal_close(cal);
|
||||
return AUTORELEASE([[NSString alloc] initWithCharactersNoCopy: result
|
||||
length: len freeWhenDone: YES]);
|
||||
#else
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#import "Foundation/NSMapTable.h"
|
||||
#import "Foundation/NSLock.h"
|
||||
#import "Foundation/NSData.h"
|
||||
#import "GSPThread.h"
|
||||
|
||||
@interface GSPlaceholderValue : NSValue
|
||||
@end
|
||||
|
@ -78,10 +79,41 @@ static Class GSPlaceholderValueClass;
|
|||
|
||||
static GSPlaceholderValue *defaultPlaceholderValue;
|
||||
static NSMapTable *placeholderMap;
|
||||
static NSLock *placeholderLock;
|
||||
static gs_mutex_t placeholderLock = GS_MUTEX_INIT_STATIC;
|
||||
|
||||
|
||||
@implementation NSValue
|
||||
|
||||
+ (void) atExit
|
||||
{
|
||||
id o;
|
||||
|
||||
/* The default placeholder array overrides -dealloc so we must get rid of
|
||||
* it directly.
|
||||
*/
|
||||
o = defaultPlaceholderValue;
|
||||
defaultPlaceholderValue = nil;
|
||||
NSDeallocateObject(o);
|
||||
|
||||
/* Deallocate all the placeholders in the map before destroying it.
|
||||
*/
|
||||
GS_MUTEX_LOCK(placeholderLock);
|
||||
if (placeholderMap)
|
||||
{
|
||||
NSMapEnumerator mEnum = NSEnumerateMapTable(placeholderMap);
|
||||
Class c;
|
||||
id o;
|
||||
|
||||
while (NSNextMapEnumeratorPair(&mEnum, (void *)&c, (void *)&o))
|
||||
{
|
||||
NSDeallocateObject(o);
|
||||
}
|
||||
NSEndMapTableEnumeration(&mEnum);
|
||||
DESTROY(placeholderMap);
|
||||
}
|
||||
GS_MUTEX_UNLOCK(placeholderLock);
|
||||
}
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (self == [NSValue class])
|
||||
|
@ -102,12 +134,9 @@ static NSLock *placeholderLock;
|
|||
*/
|
||||
defaultPlaceholderValue = (GSPlaceholderValue*)
|
||||
NSAllocateObject(GSPlaceholderValueClass, 0, NSDefaultMallocZone());
|
||||
[[NSObject leakAt: (id*)&defaultPlaceholderValue] release];
|
||||
placeholderMap = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
|
||||
NSNonRetainedObjectMapValueCallBacks, 0);
|
||||
[[NSObject leakAt: (id*)&placeholderMap] release];
|
||||
placeholderLock = [NSLock new];
|
||||
[[NSObject leakAt: (id*)&placeholderLock] release];
|
||||
[self registerAtExit];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,9 +161,9 @@ static NSLock *placeholderLock;
|
|||
* locate the correct placeholder in the (lock protected)
|
||||
* table of placeholders.
|
||||
*/
|
||||
[placeholderLock lock];
|
||||
GS_MUTEX_LOCK(placeholderLock);
|
||||
obj = (id)NSMapGet(placeholderMap, (void*)z);
|
||||
if (obj == nil)
|
||||
if (obj == nil && NO == [NSObject isExiting])
|
||||
{
|
||||
/*
|
||||
* There is no placeholder object for this zone, so we
|
||||
|
@ -143,7 +172,7 @@ static NSLock *placeholderLock;
|
|||
obj = (id)NSAllocateObject(GSPlaceholderValueClass, 0, z);
|
||||
NSMapInsert(placeholderMap, (void*)z, (void*)obj);
|
||||
}
|
||||
[placeholderLock unlock];
|
||||
GS_MUTEX_UNLOCK(placeholderLock);
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
@ -720,11 +749,13 @@ static NSLock *placeholderLock;
|
|||
|
||||
- (oneway void) release
|
||||
{
|
||||
NSWarnLog(@"-release sent to uninitialised value");
|
||||
return; // placeholders never get released.
|
||||
}
|
||||
|
||||
- (id) retain
|
||||
{
|
||||
NSWarnLog(@"-retain sent to uninitialised value");
|
||||
return self; // placeholders never get retained.
|
||||
}
|
||||
@end
|
||||
|
|
Loading…
Reference in a new issue