NSCalendarDate.m - dateByAddingYears lost timezone info.

- initWithString didn't deal with adjacent format
                   specifiers.

NSDate.m         - addTimeInterval messed up timezone if used with
                   CalendarDate.

NSArray.m        - NSMutableArray's comparered against a garbage pointer
NSGArray.m         on removal.  This causes real problems on SMP machines.

NSTimeZone.m     - The GMT+-xx files on OpenStep are in the root directory
                   and they are in Etc/* in gnustep so check both.

NSObject.m       - The release code was slightly broken for SMP machine
                   use.

NSLock.m         - Trylock was broken and lockBeforeDate unimplemented.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@5436 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
cball 1999-12-10 00:59:40 +00:00
parent c3fb857b06
commit b35bbfad7e
7 changed files with 479 additions and 291 deletions

View file

@ -900,6 +900,11 @@ static NSString *indentStrings[] = {
if (rem == 0) if (rem == 0)
rem = [self methodForSelector: remSel]; rem = [self methodForSelector: remSel];
(*rem)(self, remSel, i); (*rem)(self, remSel, i);
/*
* Bail out now or run the risk of comparing against a garbage
* pointer.
*/
return;
} }
} }
} }
@ -939,6 +944,11 @@ static NSString *indentStrings[] = {
if (rem == 0) if (rem == 0)
rem = [self methodForSelector: remSel]; rem = [self methodForSelector: remSel];
(*rem)(self, remSel, i); (*rem)(self, remSel, i);
/*
* Bail out now or run the risk of comparing against a garbage
* pointer.
*/
return;
} }
} }
} }
@ -976,6 +986,11 @@ static NSString *indentStrings[] = {
if (rem == 0) if (rem == 0)
rem = [self methodForSelector: remSel]; rem = [self methodForSelector: remSel];
(*rem)(self, remSel, i); (*rem)(self, remSel, i);
/*
* Bail out now or run the risk of comparing against a garbage
* pointer.
*/
return;
} }
} }
} }
@ -1007,6 +1022,11 @@ static NSString *indentStrings[] = {
if (rem == 0) if (rem == 0)
rem = [self methodForSelector: remSel]; rem = [self methodForSelector: remSel];
(*rem)(self, remSel, i); (*rem)(self, remSel, i);
/*
* Bail out now or run the risk of comparing against a garbage
* pointer.
*/
return;
} }
} }
} }

View file

@ -169,48 +169,57 @@
locale: nil]; locale: nil];
} }
/*
* This function could possibly be written better
* but it works ok; currently ignores locale
* information and some specifiers.
*/
- (id) initWithString: (NSString *)description
calendarFormat: (NSString *)format
locale: (NSDictionary *)locale
{
const char *d = [description cString];
const char *f = [format cString];
char *newf;
int lf = strlen(f);
BOOL mtag = NO, dtag = NO, ycent = NO;
BOOL fullm = NO;
char ms[80] = "", ds[80] = "", timez[80] = "", ampm[80] = "";
int tznum = 0;
int yd = 0, md = 0, dd = 0, hd = 0, mnd = 0, sd = 0;
void *pntr[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int order;
int yord = 0, mord = 0, dord = 0, hord = 0, mnord = 0, sord = 0, tzord = 0;
int ampmord = 0;
int i;
NSTimeZone *tz;
BOOL zoneByAbbreviation = YES;
// If either the string or format is nil then raise exception - (id) initWithString: (NSString *)description
if (!description) calendarFormat: (NSString *)fmt
[NSException raise: NSInvalidArgumentException locale: (NSDictionary *)locale
format: @"NSCalendar date description is nil"]; {
int year = 0, month = 1, day = 1, hour = 0, min = 0, sec = 0;
NSTimeZone *tz = [NSTimeZone localTimeZone];
int ampm = 0, twelveHrClock = 0;
int julianWeeks = -1, weekStartsMonday = 0, dayOfWeek = -1;
const char *source = [description cString];
int sourceLen = strlen(source);
const char *format = [fmt cString];
int formatLen = strlen(format);
int formatIdx = 0;
int sourceIdx = 0;
char tmpStr[20];
int tmpIdx;
if (locale == nil) if (locale == nil)
locale = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]; {
if (format == nil) locale = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
format = [locale objectForKey: NSTimeDateFormatString]; }
if (fmt == nil)
{
format = [[locale objectForKey: NSTimeDateFormatString] cString];
formatLen = strlen(format);
}
// The strftime specifiers //
// WARNING:
// -%c, %F, %x, %X do NOT work. (NSTimeDateFormatString isn't defined and
// the underlying call has granularity to the second.
// -Most locale stuff is dubious at best.
// -Long day and month names depend on a non-alpha character after the last
// digit to work.
//
// The strftime specifiers as used by OpenStep + %U.
//
// %% literal % character
// %a abbreviated weekday name according to locale // %a abbreviated weekday name according to locale
// %A full weekday name according to locale // %A full weekday name according to locale
// %b abbreviated month name according to locale // %b abbreviated month name according to locale
// %B full month name according to locale // %B full month name according to locale
// %c same as '%X %x'
// %d day of month as decimal number // %d day of month as decimal number
// %e same as %d without leading zero (you get a leading space instead)
// %F milliseconds as a decimal number
// %H hour as a decimal number using 24-hour clock // %H hour as a decimal number using 24-hour clock
// %I hour as a decimal number using 12-hour clock // %I hour as a decimal number using 12-hour clock
// %j day of year as a decimal number // %j day of year as a decimal number
@ -221,253 +230,308 @@
// %U week of the current year as decimal number (Sunday first day) // %U week of the current year as decimal number (Sunday first day)
// %W week of the current year as decimal number (Monday first day) // %W week of the current year as decimal number (Monday first day)
// %w day of the week as decimal number (Sunday = 0) // %w day of the week as decimal number (Sunday = 0)
// %y year as a decimal number without century // %x date with date representation for locale
// %X time with time representation for locale
// %y year as a decimal number without century
// %Y year as a decimal number with century // %Y year as a decimal number with century
// %Z time zone // %z time zone offset in hours and minutes from GMT (HHMM)
// %% literal % character // %Z time zone abbreviation
while ( formatIdx < formatLen )
// Find the order of date elements
// and translate format string into scanf ready string
order = 1;
newf = NSZoneMalloc(NSDefaultMallocZone(), lf+1);
for (i = 0;i < lf; ++i)
{
newf[i] = f[i];
// Only care about a format specifier
if (f[i] == '%')
{ {
// check the character that comes after if ( format[formatIdx] != '%' )
switch (f[i+1])
{
// skip literal %
case '%':
++i;
newf[i] = f[i];
break;
// is it the year
case 'Y':
ycent = YES;
case 'y':
yord = order;
++order;
++i;
newf[i] = 'd';
pntr[yord] = (void *)&yd;
break;
// is it the month
case 'B':
fullm = YES; // Full month name
case 'b':
mtag = YES; // Month is character string
case 'm':
mord = order;
++order;
++i;
if (mtag)
{ {
newf[i] = 's'; // If it's not a format specifier, ignore it.
pntr[mord] = (void *)ms; sourceIdx++;
} } else {
else
{
newf[i] = 'd';
pntr[mord] = (void *)&md;
}
break;
// is it the day // Skip '%'
case 'a': formatIdx++;
case 'A':
dtag = YES; // Day is character string
case 'd':
case 'j':
case 'w':
dord = order;
++order;
++i;
if (dtag)
{
newf[i] = 's';
pntr[dord] = (void *)ds;
}
else
{
newf[i] = 'd';
pntr[dord] = (void *)&dd;
}
break;
// is it the hour switch (format[formatIdx])
case 'H': {
case 'I': case '%':
hord = order; // skip literal %
++order; sourceIdx++;
++i; break;
newf[i] = 'd';
pntr[hord] = (void *)&hd;
break;
// is it the minute case 'a':
case 'M': // Are Short names three chars in all locales?????
mnord = order; tmpStr[0] = toupper( source[sourceIdx++] );
++order; tmpStr[1] = tolower( source[sourceIdx++] );
++i; tmpStr[2] = tolower( source[sourceIdx++] );
newf[i] = 'd'; tmpStr[3] = '\0';
pntr[mnord] = (void *)&mnd; {
break; NSString *currDay = [NSString stringWithCString: tmpStr];
NSArray *dayNames = [locale objectForKey: NSShortWeekDayNameArray];
// is it the second for (tmpIdx = 0; tmpIdx < 7; tmpIdx++)
case 'S': if ([[dayNames objectAtIndex: tmpIdx] isEqual: currDay] == YES)
sord = order; break;
++order; dayOfWeek = tmpIdx;
++i; }
newf[i] = 'd'; break;
pntr[sord] = (void *)&sd;
break;
// the time zone abbreviation case 'A':
case 'Z': for ( tmpIdx = sourceIdx; tmpIdx < sourceLen; tmpIdx++ )
tzord = order; {
++order; if ( isalpha( source[tmpIdx] ) )
++i; {
newf[i] = 's'; tmpStr[tmpIdx - sourceIdx] = source[tmpIdx];
pntr[tzord] = (void *)timez; } else {
break; break;
}
}
tmpStr[tmpIdx - sourceIdx] = '\0';
sourceIdx += tmpIdx - sourceIdx;
{
NSString *currDay = [NSString stringWithCString: tmpStr];
NSArray *dayNames = [locale objectForKey: NSWeekDayNameArray];
// the time zone in numeric format for (tmpIdx = 0; tmpIdx < 7; tmpIdx++)
case 'z': if ([[dayNames objectAtIndex: tmpIdx] isEqual: currDay] == YES)
tzord = order; break;
++order; dayOfWeek = tmpIdx;
++i; }
newf[i] = 'd'; break;
pntr[tzord] = (void *)&tznum;
zoneByAbbreviation = NO;
break;
// AM PM indicator case 'b':
case 'p': // Are Short names three chars in all locales?????
ampmord = order; tmpStr[0] = toupper( source[sourceIdx++] );
++order; tmpStr[1] = tolower( source[sourceIdx++] );
++i; tmpStr[2] = tolower( source[sourceIdx++] );
newf[i] = 's'; tmpStr[3] = '\0';
pntr[ampmord] = (void *)ampm; {
break; NSString *currMonth = [NSString stringWithCString: tmpStr];
NSArray *monthNames = [locale objectForKey: NSShortMonthNameArray];
// Anything else is an invalid format for (tmpIdx = 0; tmpIdx < 12; tmpIdx++)
default: {
free(newf); if ([[monthNames objectAtIndex: tmpIdx] isEqual: currMonth] == YES)
[NSException raise: NSInvalidArgumentException break;
format: @"Invalid NSCalendar date, specifier %c not recognized in format %s", f[i+1], f]; }
} month = tmpIdx+1;
}
break;
case 'B':
for ( tmpIdx = sourceIdx; tmpIdx < sourceLen; tmpIdx++ )
{
if ( isalpha( source[tmpIdx] ) )
{
tmpStr[tmpIdx - sourceIdx] = source[tmpIdx];
} else {
break;
}
}
tmpStr[tmpIdx - sourceIdx] = '\0';
sourceIdx += tmpIdx - sourceIdx;
{
NSString *currMonth = [NSString stringWithCString: tmpStr];
NSArray *monthNames = [locale objectForKey: NSMonthNameArray];
for (tmpIdx = 0; tmpIdx < 12; tmpIdx++)
if ([[monthNames objectAtIndex: tmpIdx] isEqual: currMonth] == YES)
break;
month = tmpIdx+1;
}
break;
// case 'c':
// break;
case 'd': // fall through
case 'e':
memcpy( tmpStr, &source[sourceIdx], 2 );
tmpStr[2] = '\0';
sourceIdx += 2;
day = atoi( tmpStr );
break;
// case 'F':
// break;
case 'I': // fall through
twelveHrClock = 1;
case 'H':
memcpy( tmpStr, &source[sourceIdx], 2 );
tmpStr[2] = '\0';
sourceIdx += 2;
hour = atoi( tmpStr );
break;
case 'j':
memcpy( tmpStr, &source[sourceIdx], 3 );
tmpStr[3] = '\0';
sourceIdx += 3;
day = atoi( tmpStr );
break;
case 'm':
memcpy( tmpStr, &source[sourceIdx], 2 );
tmpStr[2] = '\0';
sourceIdx += 2;
month = atoi( tmpStr );
break;
case 'M':
memcpy( tmpStr, &source[sourceIdx], 2 );
tmpStr[2] = '\0';
sourceIdx += 2;
min = atoi( tmpStr );
break;
case 'p':
// Questionable assumption that all am/pm indicators are 2
// characters and in upper case....
tmpStr[0] = toupper( source[sourceIdx++] );
tmpStr[1] = toupper( source[sourceIdx++] );
tmpStr[2] = '\0';
{
NSString *currAMPM = [NSString stringWithCString: tmpStr];
NSArray *amPMNames = [locale objectForKey: NSAMPMDesignation];
/*
* The time addition is handled below because this
* indicator only modifies the time on a 12hour clock.
*/
if ([[amPMNames objectAtIndex: 1] isEqual: currAMPM] == YES)
ampm = 1;
}
break;
case 'S':
memcpy( tmpStr, &source[sourceIdx], 2 );
tmpStr[2] = '\0';
sourceIdx += 2;
sec = atoi( tmpStr );
break;
case 'w':
tmpStr[0] = source[sourceIdx++];
tmpStr[1] = '\0';
dayOfWeek = atoi( tmpStr );
break;
case 'W': // Fall through
weekStartsMonday = 1;
case 'U':
memcpy( tmpStr, &source[sourceIdx], 2 );
tmpStr[2] = '\0';
sourceIdx += 2;
julianWeeks = atoi( tmpStr );
break;
// case 'x':
// break;
// case 'X':
// break;
case 'y':
memcpy( tmpStr, &source[sourceIdx], 2 );
tmpStr[2] = '\0';
sourceIdx += 2;
year = atoi( tmpStr );
if ( year >= 70 )
{
year += 1900;
} else {
year += 2000;
}
break;
case 'Y':
memcpy( tmpStr, &source[sourceIdx], 4 );
tmpStr[4] = '\0';
sourceIdx += 4;
year = atoi( tmpStr );
break;
case 'z':
tmpStr[0] = toupper( source[sourceIdx++] );
tmpStr[1] = tolower( source[sourceIdx++] );
tmpStr[2] = tolower( source[sourceIdx++] );
tmpStr[3] = tolower( source[sourceIdx++] );
tmpStr[4] = '\0';
{
int zone;
zone = atoi( tmpStr );
if ((tz = [NSTimeZone timeZoneForSecondsFromGMT:
(zone / 100 * 60 + (zone % 100) ) * 60] ) == nil )
{
tz = [NSTimeZone localTimeZone];
}
}
break;
case 'Z':
for ( tmpIdx = sourceIdx; tmpIdx < sourceLen; tmpIdx++ )
{
if ( isalpha( source[tmpIdx] ) || source[tmpIdx] == '-' || source[tmpIdx] == '+' )
{
tmpStr[tmpIdx - sourceIdx] = source[tmpIdx];
} else {
break;
}
}
tmpStr[tmpIdx - sourceIdx] = '\0';
sourceIdx += tmpIdx - sourceIdx;
{
if ( (tz = [NSTimeZone timeZoneWithAbbreviation:
[NSString stringWithCString: tmpStr]]) == nil)
{
tz = [NSTimeZone localTimeZone];
}
}
break;
default:
[NSException raise: NSInvalidArgumentException
format: @"Invalid NSCalendar date, specifier %c not recognized in format %s",
format[formatIdx], format];
}
}
formatIdx++;
} }
}
newf[lf] = '\0';
// Have sscanf parse and retrieve the values for us if ( twelveHrClock )
if (order != 1) {
sscanf(d, newf, pntr[1], pntr[2], pntr[3], pntr[4], pntr[5], pntr[6], if ( ampm && hour != 12 )
pntr[7], pntr[8], pntr[9]); {
else hour += 12;
// nothing in the string? }
; }
// Put century on year if need be if ( julianWeeks != -1 )
// +++ How do we be year 2000 compliant? {
if (!ycent) int currDay = [[[[NSCalendarDate alloc] initWithYear: year month: 1 day: 1 hour: 0 minute: 0
yd += 1900; second: 0 timeZone: [NSTimeZone timeZoneForSecondsFromGMT: 0]] autorelease] dayOfWeek];
// Possibly convert month from string to decimal number /*
if (mtag) * The julian weeks are either sunday relative or monday relative but all
{ * of the day of week specifiers are sunday relative. This means that if
int i; * no day of week specifier was used the week starts on monday.
NSString *m = [NSString stringWithCString: ms]; */
if ( dayOfWeek == -1 )
{
if ( weekStartsMonday )
{
dayOfWeek = 1;
} else {
dayOfWeek = 0;
}
}
day = dayOfWeek + (julianWeeks * 7 - (currDay - 1));
}
if (fullm) return [[NSCalendarDate alloc] initWithYear: year month: month day: day hour: hour
{ minute: min second: sec
NSArray *names = [locale objectForKey: NSMonthNameArray];
for (i = 0;i < 12; ++i)
if ([[names objectAtIndex: i] isEqual: m] == YES)
break;
}
else
{
NSArray *names = [locale objectForKey: NSShortMonthNameArray];
for (i = 0;i < 12; ++i)
if ([[names objectAtIndex: i] isEqual: m] == YES)
break;
}
md = i + 1;
}
// Possibly convert day from string to decimal number
// +++ how do we take locale into account?
if (dtag)
{
}
// +++ We need to take 'am' and 'pm' into account
if (ampmord)
{
// If its PM then we shift
if ((ampm[0] == 'p') || (ampm[0] == 'P'))
{
// 12pm is 12pm not 24pm
if (hd != 12)
hd += 12;
}
}
// +++ then there is the time zone
if (tzord)
{
if (zoneByAbbreviation)
{
tz = [NSTimeZone timeZoneWithAbbreviation:
[NSString stringWithCString: timez]];
if (!tz)
{
tz = [NSTimeZone localTimeZone];
}
}
else
{
int tzm, tzh, sign;
if (tznum < 0)
{
sign = -1;
tznum = -tznum;
}
else
{
sign = 1;
}
tzm = tznum % 100;
tzh = tznum / 100;
tz = [NSTimeZone timeZoneForSecondsFromGMT: (tzh*60 + tzm)*60*sign];
if (!tz)
{
tz = [NSTimeZone localTimeZone];
}
}
}
else
{
tz = [NSTimeZone localTimeZone];
}
NSZoneFree(NSDefaultMallocZone(), newf);
return [self initWithYear: yd month: md day: dd hour: hd
minute: mnd second: sd
timeZone: tz]; timeZone: tz];
} }
- (id) initWithYear: (int)year - (id) initWithYear: (int)year
month: (unsigned int)month month: (unsigned int)month
day: (unsigned int)day day: (unsigned int)day
@ -1252,7 +1316,7 @@
hour: hour hour: hour
minute: minute minute: minute
second: second second: second
timeZone: nil]; timeZone: [self timeZoneDetail]];
} }
- (void) years: (int*)years - (void) years: (int*)years

View file

@ -1118,8 +1118,13 @@ GSTimeNow()
- (id) addTimeInterval: (NSTimeInterval)seconds - (id) addTimeInterval: (NSTimeInterval)seconds
{ {
/* xxx We need to check for overflow? */ /* xxx We need to check for overflow? */
return [concreteClass dateWithTimeIntervalSinceReferenceDate: id newObj = [[self class] dateWithTimeIntervalSinceReferenceDate:
_seconds_since_ref + seconds]; _seconds_since_ref + seconds];
if ([self isKindOfClass: [NSCalendarDate class]])
[newObj setTimeZone: [(NSCalendarDate *) self timeZoneDetail]];
return newObj;
} }
- (NSTimeInterval) timeIntervalSince1970 - (NSTimeInterval) timeIntervalSince1970

View file

@ -450,6 +450,11 @@ static SEL eqSel = @selector(isEqual:);
} }
_count--; _count--;
RELEASE(obj); RELEASE(obj);
/*
* Bail out now or run the risk of comparing against a garbage
* pointer.
*/
return;
} }
} }
} }
@ -500,6 +505,11 @@ static SEL eqSel = @selector(isEqual:);
} }
_count--; _count--;
RELEASE(obj); RELEASE(obj);
/*
* Bail out now or run the risk of comparing against a garbage
* pointer.
*/
return;
} }
} }
} }

View file

@ -1,5 +1,5 @@
/* Mutual exclusion locking classes /* Mutual exclusion locking classes
Copyright (C) 1996 Free Software Foundation< Inc. Copyright (C) 1996 Free Software Foundation, Inc.
Author: Scott Christley <scottc@net-community.com> Author: Scott Christley <scottc@net-community.com>
Created: 1996 Created: 1996
@ -9,7 +9,7 @@
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
version 2 of the License< or (at your option) any later version. version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -17,12 +17,13 @@
Library General Public License for more details. Library General Public License for more details.
You should have received a copy of the GNU Library General Public You should have received a copy of the GNU Library General Public
License along with this library; if not< write to the Free License along with this library; if not, write to the Free
Software Foundation< Inc.< 59 Temple Place< Suite 330< Boston< MA 02111 USA. Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/ */
#include <config.h> #include <config.h>
#include <errno.h> #include <errno.h>
#include <unistd.h>
#include <base/preface.h> #include <base/preface.h>
#include <Foundation/NSLock.h> #include <Foundation/NSLock.h>
#include <Foundation/NSException.h> #include <Foundation/NSException.h>
@ -94,19 +95,52 @@ NSString *NSRecursiveLockException = @"NSRecursiveLockException";
// Does not block // Does not block
- (BOOL) tryLock - (BOOL) tryLock
{ {
CHECK_RECURSIVE_LOCK(_mutex);
// Ask the runtime to acquire a lock on the mutex // Ask the runtime to acquire a lock on the mutex
if (objc_mutex_trylock(_mutex) == -1) if (objc_mutex_trylock(_mutex) == -1)
return NO; {
else return NO;
return YES; } else {
/*
* The recursive lock check goes here to support openstep's
* implementation. In openstep you can lock in one thread trylock in the
* same thread and have another thread release the lock.
*
* This is dangerous and broken IMHO.
*/
CHECK_RECURSIVE_LOCK(_mutex);
return YES;
}
} }
- (BOOL) lockBeforeDate: (NSDate *)limit - (BOOL) lockBeforeDate: (NSDate *)limit
{ {
[self notImplemented: _cmd]; int x;
return NO;
while ((x = objc_mutex_trylock (_mutex)) == -1 )
{
NSDate *current = [NSDate date];
NSComparisonResult compare;
compare = [current compare: limit];
if ( compare == NSOrderedSame || compare == NSOrderedDescending )
{
return NO;
}
/*
* This should probably be more accurate like usleep(250)
* but usleep is known to NOT be thread safe under all architectures.
*/
sleep(1);
}
/*
* The recursive lock check goes here to support openstep's implementation.
* In openstep you can lock in one thread trylock in the same thread and have
* another thread release the lock.
*
* This is dangerous and broken IMHO.
*/
CHECK_RECURSIVE_LOCK(_mutex);
return YES;
} }
// NSLocking protocol // NSLocking protocol
@ -236,7 +270,7 @@ NSString *NSRecursiveLockException = @"NSRecursiveLockException";
} }
// If the depth is only 1 then we just acquired // If the depth is only 1 then we just acquired
// the lock above< bogus unlock so abort // the lock above, bogus unlock so abort
if (depth == 1) if (depth == 1)
{ {
[NSException raise:NSConditionLockException [NSException raise:NSConditionLockException
@ -297,9 +331,26 @@ NSString *NSRecursiveLockException = @"NSRecursiveLockException";
// Acquiring the lock with a date condition // Acquiring the lock with a date condition
- (BOOL) lockBeforeDate: (NSDate*)limit - (BOOL) lockBeforeDate: (NSDate*)limit
{ {
[self notImplemented: _cmd]; CHECK_RECURSIVE_CONDITION_LOCK(_mutex);
return NO;
while ( objc_mutex_trylock (_mutex) == -1 )
{
NSDate *current = [NSDate date];
NSComparisonResult compare;
compare = [current compare: limit];
if ( compare == NSOrderedSame || compare == NSOrderedDescending )
{
return NO;
}
/*
* This should probably be more accurate like usleep(250)
* but usleep is known to NOT be thread safe under all architectures.
*/
sleep(1);
}
return YES;
} }
@ -437,8 +488,23 @@ NSString *NSRecursiveLockException = @"NSRecursiveLockException";
- (BOOL) lockBeforeDate: (NSDate *)limit - (BOOL) lockBeforeDate: (NSDate *)limit
{ {
[self notImplemented: _cmd]; while ( objc_mutex_trylock (_mutex) == -1 )
return NO; {
NSDate *current = [NSDate date];
NSComparisonResult compare;
compare = [current compare: limit];
if ( compare == NSOrderedSame || compare == NSOrderedDescending )
{
return NO;
}
/*
* This should probably be more accurate like usleep(250)
* but usleep is known to NOT be thread safe under all architectures.
*/
sleep(1);
}
return YES;
} }
// NSLocking protocol // NSLocking protocol

View file

@ -175,32 +175,42 @@ NSDecrementExtraRefCountWasZero(id anObject)
* depending on whether we are using local or global counting. * depending on whether we are using local or global counting.
*/ */
#if defined(REFCNT_LOCAL) #if defined(REFCNT_LOCAL)
unsigned unsigned
NSExtraRefCount(id anObject) NSExtraRefCount(id anObject)
{ {
return ((obj)anObject)[-1].retained; return ((obj)anObject)[-1].retained;
} }
static objc_mutex_t retain_counts_gate = NULL;
void void
NSIncrementExtraRefCount(id anObject) NSIncrementExtraRefCount(id anObject)
{ {
objc_mutex_lock (retain_counts_gate);
((obj)anObject)[-1].retained++; ((obj)anObject)[-1].retained++;
objc_mutex_unlock (retain_counts_gate);
} }
#define NSIncrementExtraRefCount(X) \ #define NSIncrementExtraRefCount(X) \
((obj)(X))[-1].retained++ objc_mutex_lock (retain_counts_gate); \
((obj)(X))[-1].retained++; \
objc_mutex_unlock (retain_counts_gate)
BOOL BOOL
NSDecrementExtraRefCountWasZero(id anObject) NSDecrementExtraRefCountWasZero(id anObject)
{ {
objc_mutex_lock (retain_counts_gate);
if (((obj)anObject)[-1].retained-- == 0) if (((obj)anObject)[-1].retained-- == 0)
return YES; {
else objc_mutex_unlock (retain_counts_gate);
return NO; return YES;
} else {
objc_mutex_unlock (retain_counts_gate);
return NO;
}
} }
#define NSDecrementExtraRefCountWasZero(X) \
(((obj)(X))[-1].retained-- == 0 ? YES : NO)
#define NSExtraRefCount(X) (((obj)(X))[-1].retained) #define NSExtraRefCount(X) (((obj)(X))[-1].retained)
@ -518,8 +528,12 @@ static BOOL double_release_check_enabled = NO;
#if !defined(REFCNT_LOCAL) #if !defined(REFCNT_LOCAL)
retain_counts = o_map_with_callbacks (o_callbacks_for_non_owned_void_p, retain_counts = o_map_with_callbacks (o_callbacks_for_non_owned_void_p,
o_callbacks_for_int); o_callbacks_for_int);
retain_counts_gate = objc_mutex_allocate ();
#endif #endif
/*
* retain_counts_gate is needed on SMP machines for release to work
* reliably.
*/
retain_counts_gate = objc_mutex_allocate ();
fastMallocOffset = fastMallocClass->instance_size % ALIGN; fastMallocOffset = fastMallocClass->instance_size % ALIGN;
#else #else
fastMallocOffset = 0; fastMallocOffset = 0;

View file

@ -972,12 +972,21 @@ static NSMapTable *absolutes = 0;
+ (NSString*) getTimeZoneFile: (NSString *)name + (NSString*) getTimeZoneFile: (NSString *)name
{ {
/*
* OpenStep does NOT put all the GMT+-* timezones in the Etc directory so all
* the OpenStep software will fail to work without this extra hack.
*/
NSString *fileName = [NSString stringWithFormat: @"%@%@", NSString *fileName = [NSString stringWithFormat: @"%@%@",
ZONES_DIR, name]; ZONES_DIR, name];
NSString *path = [NSBundle pathForGNUstepResource: fileName
return [NSBundle pathForGNUstepResource: fileName
ofType: @"" ofType: @""
inDirectory: TIME_ZONE_DIR]; inDirectory: TIME_ZONE_DIR];
if ( !path )
{
return [self getTimeZoneFile: [NSString stringWithFormat: @"Etc/%@", name]];
}
return path;
} }
@end @end