mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
Optimisation mostly
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@4098 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
832c4c2ec2
commit
84e7ffcdef
17 changed files with 697 additions and 319 deletions
|
@ -41,7 +41,7 @@ struct autorelease_thread_vars
|
|||
|
||||
/* The total number of objects autoreleased since the thread was
|
||||
started, or since -resetTotalAutoreleasedObjects was called
|
||||
in this thread. */
|
||||
in this thread. (if compiled in) */
|
||||
unsigned total_objects_count;
|
||||
|
||||
/* A cache of NSAutoreleasePool's already alloc'ed. Caching old pools
|
||||
|
@ -90,6 +90,11 @@ struct autorelease_array_list
|
|||
+ (void) enableRelease: (BOOL)enable;
|
||||
+ (void) setPoolCountThreshhold: (unsigned)c;
|
||||
+ (unsigned) autoreleaseCountForObject: anObject;
|
||||
/*
|
||||
* The next two methods have no effect unless you define COUNT_ALL to be
|
||||
* 1 in NSAutoreleasepool.m - doing so incurs a thread lookup overhead
|
||||
* each time an object is autoreleased.
|
||||
*/
|
||||
+ (void) resetTotalAutoreleasedObjects;
|
||||
+ (unsigned) totalAutoreleasedObjects;
|
||||
#endif
|
||||
|
|
|
@ -34,9 +34,7 @@ typedef double NSTimeInterval;
|
|||
@class NSTimeZoneDetail;
|
||||
|
||||
@interface NSDate : NSObject <NSCoding,NSCopying>
|
||||
|
||||
{
|
||||
NSTimeInterval seconds_since_ref;
|
||||
}
|
||||
|
||||
// Getting current time
|
||||
|
@ -97,6 +95,19 @@ typedef double NSTimeInterval;
|
|||
|
||||
@end
|
||||
|
||||
#ifndef NO_GNUSTEP
|
||||
/*
|
||||
* Our concrete base class - NSCalendar date must share the ivar layout.
|
||||
*/
|
||||
@interface NSGDate : NSDate
|
||||
{
|
||||
@public
|
||||
NSTimeInterval seconds_since_ref;
|
||||
}
|
||||
@end
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@interface NSTimeZone : NSObject
|
||||
|
||||
|
@ -141,8 +152,9 @@ typedef double NSTimeInterval;
|
|||
@interface NSCalendarDate : NSDate
|
||||
|
||||
{
|
||||
NSString *calendar_format;
|
||||
NSTimeZoneDetail *time_zone;
|
||||
NSTimeInterval seconds_since_ref;
|
||||
NSString *calendar_format;
|
||||
NSTimeZoneDetail *time_zone;
|
||||
}
|
||||
|
||||
// Getting an NSCalendar Date
|
||||
|
|
|
@ -52,6 +52,10 @@ extern int errno;
|
|||
* If 'changeFlag' is YES then the list gives the number
|
||||
* of instances allocated/deallocated sine the function
|
||||
* was last called.
|
||||
* GSDebugAllocationListAll()
|
||||
* Returns a newline separated list of the classes which
|
||||
* have had instances allocated at any point, and the total
|
||||
* count of the number of instances allocated.
|
||||
*/
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
|
|
@ -34,11 +34,14 @@ extern id NSDefaultRunLoopMode;
|
|||
|
||||
@interface NSRunLoop : NSObject <GCFinalization>
|
||||
{
|
||||
@private id _current_mode;
|
||||
@private NSMapTable *_mode_2_timers;
|
||||
@private NSMapTable *_mode_2_watchers;
|
||||
@private NSMutableArray *_performers;
|
||||
@private NSMutableArray *_timedPerformers;
|
||||
@private
|
||||
id _current_mode;
|
||||
NSMapTable *_mode_2_timers;
|
||||
NSMapTable *_mode_2_watchers;
|
||||
NSMutableArray *_performers;
|
||||
NSMutableArray *_timedPerformers;
|
||||
NSMapTable *_rfdMap;
|
||||
NSMapTable *_wfdMap;
|
||||
}
|
||||
|
||||
+ (NSRunLoop*) currentRunLoop;
|
||||
|
|
|
@ -65,4 +65,12 @@ typedef enum
|
|||
extern NSString *NSBecomingMultiThreaded;
|
||||
extern NSString *NSThreadExiting;
|
||||
|
||||
#ifndef NO_GNUSTEP
|
||||
/*
|
||||
* Get current thread and it's dictionary.
|
||||
*/
|
||||
extern NSThread *GSCurrentThread();
|
||||
extern NSMutableDictionary *GSCurrentThreadDictionary();
|
||||
#endif
|
||||
|
||||
#endif /* __NSThread_h_GNUSTEP_BASE_INCLUDE */
|
||||
|
|
|
@ -38,7 +38,7 @@ static NSString *dict_key = @"_NSAssertionHandler";
|
|||
NSMutableDictionary *dict;
|
||||
NSAssertionHandler *handler;
|
||||
|
||||
dict = [[NSThread currentThread] threadDictionary];
|
||||
dict = GSCurrentThreadDictionary();
|
||||
handler = [dict objectForKey: dict_key];
|
||||
if (handler == nil)
|
||||
{
|
||||
|
|
|
@ -29,9 +29,10 @@
|
|||
#include <Foundation/NSZone.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* TODO:
|
||||
Doesn't work multi-threaded.
|
||||
*/
|
||||
/*
|
||||
* Set to 1 to count all autoreleases
|
||||
*/
|
||||
#define COUNT_ALL 0
|
||||
|
||||
/* When this is `NO', autoreleased objects are never actually recorded
|
||||
in an NSAutoreleasePool, and are not sent a `release' message.
|
||||
|
@ -46,7 +47,7 @@ static unsigned pool_count_warning_threshhold = UINT_MAX;
|
|||
#define BEGINNING_POOL_SIZE 32
|
||||
|
||||
/* Easy access to the thread variables belonging to NSAutoreleasePool. */
|
||||
#define ARP_THREAD_VARS (&([NSThread currentThread]->_autorelease_vars))
|
||||
#define ARP_THREAD_VARS (&(GSCurrentThread()->_autorelease_vars))
|
||||
|
||||
|
||||
@interface NSAutoreleasePool (Private)
|
||||
|
@ -280,9 +281,11 @@ static IMP initImp;
|
|||
_released->objects[_released->count] = anObj;
|
||||
(_released->count)++;
|
||||
|
||||
#if COUNT_ALL
|
||||
/* Keep track of the total number of objects autoreleased across all
|
||||
pools. */
|
||||
ARP_THREAD_VARS->total_objects_count++;
|
||||
#endif
|
||||
|
||||
/* Keep track of the total number of objects autoreleased in this pool */
|
||||
_released_count++;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <Foundation/NSCoder.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSUserDefaults.h>
|
||||
#include <base/behavior.h>
|
||||
|
||||
#ifndef __WIN32__
|
||||
#include <time.h>
|
||||
|
@ -54,46 +55,57 @@
|
|||
|
||||
@interface NSCalendarDate (Private)
|
||||
|
||||
- (void)getYear:(int *)year month:(int *)month day:(int *)day
|
||||
hour:(int *)hour minute:(int *)minute second:(int *)second;
|
||||
- (void)getYear: (int *)year month: (int *)month day: (int *)day
|
||||
hour: (int *)hour minute: (int *)minute second: (int *)second;
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSCalendarDate
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (self == [NSCalendarDate class])
|
||||
{
|
||||
[self setVersion: 1];
|
||||
behavior_class_add_class(self, [NSGDate class]);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Getting an NSCalendar Date
|
||||
//
|
||||
+ (id)calendarDate
|
||||
{
|
||||
return [[[self alloc] init] autorelease];
|
||||
id d = [[self alloc] init];
|
||||
|
||||
return AUTORELEASE(d);
|
||||
}
|
||||
|
||||
+ (id)dateWithString:(NSString *)description
|
||||
calendarFormat:(NSString *)format
|
||||
+ (id)dateWithString: (NSString *)description
|
||||
calendarFormat: (NSString *)format
|
||||
{
|
||||
NSCalendarDate *d = [[NSCalendarDate alloc] initWithString: description
|
||||
calendarFormat: format];
|
||||
return [d autorelease];
|
||||
return AUTORELEASE(d);
|
||||
}
|
||||
|
||||
+ (id)dateWithString:(NSString *)description
|
||||
calendarFormat:(NSString *)format
|
||||
locale:(NSDictionary *)dictionary
|
||||
+ (id)dateWithString: (NSString *)description
|
||||
calendarFormat: (NSString *)format
|
||||
locale: (NSDictionary *)dictionary
|
||||
{
|
||||
NSCalendarDate *d = [[NSCalendarDate alloc] initWithString: description
|
||||
calendarFormat: format
|
||||
locale: dictionary];
|
||||
return [d autorelease];
|
||||
return AUTORELEASE(d);
|
||||
}
|
||||
|
||||
+ (id)dateWithYear:(int)year
|
||||
month:(unsigned int)month
|
||||
day:(unsigned int)day
|
||||
hour:(unsigned int)hour
|
||||
minute:(unsigned int)minute
|
||||
second:(unsigned int)second
|
||||
timeZone:(NSTimeZone *)aTimeZone
|
||||
+ (id)dateWithYear: (int)year
|
||||
month: (unsigned int)month
|
||||
day: (unsigned int)day
|
||||
hour: (unsigned int)hour
|
||||
minute: (unsigned int)minute
|
||||
second: (unsigned int)second
|
||||
timeZone: (NSTimeZone *)aTimeZone
|
||||
{
|
||||
NSCalendarDate *d = [[NSCalendarDate alloc] initWithYear: year
|
||||
month: month
|
||||
|
@ -102,32 +114,42 @@
|
|||
minute: minute
|
||||
second: second
|
||||
timeZone: aTimeZone];
|
||||
return [d autorelease];
|
||||
return AUTORELEASE(d);
|
||||
}
|
||||
|
||||
- (void) encodeWithCoder: (NSCoder*)aCoder
|
||||
- (Class) classForPortCoder
|
||||
{
|
||||
[super encodeWithCoder: aCoder];
|
||||
[aCoder encodeObject: calendar_format];
|
||||
[aCoder encodeObject: time_zone];
|
||||
return [self class];
|
||||
}
|
||||
|
||||
- (id) initWithCoder: (NSCoder*)aCoder
|
||||
- replacementObjectForPortCoder: aRmc
|
||||
{
|
||||
self = [super initWithCoder: aCoder];
|
||||
[aCoder decodeValueOfObjCType: @encode(id) at: &calendar_format];
|
||||
[aCoder decodeValueOfObjCType: @encode(id) at: &time_zone];
|
||||
return self;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) encodeWithCoder: (NSCoder*)coder
|
||||
{
|
||||
[coder encodeValueOfObjCType: @encode(NSTimeInterval) at: &seconds_since_ref];
|
||||
[coder encodeObject: calendar_format];
|
||||
[coder encodeObject: time_zone];
|
||||
}
|
||||
|
||||
- (id) initWithCoder: (NSCoder*)coder
|
||||
{
|
||||
[coder decodeValueOfObjCType: @encode(NSTimeInterval) at: &seconds_since_ref];
|
||||
[coder decodeValueOfObjCType: @encode(id) at: &calendar_format];
|
||||
[coder decodeValueOfObjCType: @encode(id) at: &time_zone];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[calendar_format release];
|
||||
[super dealloc];
|
||||
RELEASE(calendar_format);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
// Initializing an NSCalendar Date
|
||||
- (id)initWithString:(NSString *)description
|
||||
- (id)initWithString: (NSString *)description
|
||||
{
|
||||
// +++ What is the locale?
|
||||
return [self initWithString: description
|
||||
|
@ -135,8 +157,8 @@
|
|||
locale: nil];
|
||||
}
|
||||
|
||||
- (id)initWithString:(NSString *)description
|
||||
calendarFormat:(NSString *)format
|
||||
- (id)initWithString: (NSString *)description
|
||||
calendarFormat: (NSString *)format
|
||||
{
|
||||
// ++ What is the locale?
|
||||
return [self initWithString: description
|
||||
|
@ -149,9 +171,9 @@
|
|||
// but it works ok; currently ignores locale
|
||||
// information and some specifiers.
|
||||
//
|
||||
- (id)initWithString:(NSString *)description
|
||||
calendarFormat:(NSString *)format
|
||||
locale:(NSDictionary *)locale
|
||||
- (id)initWithString: (NSString *)description
|
||||
calendarFormat: (NSString *)format
|
||||
locale: (NSDictionary *)locale
|
||||
{
|
||||
const char *d = [description cString];
|
||||
const char *f = [format cString];
|
||||
|
@ -357,7 +379,7 @@
|
|||
{
|
||||
int i;
|
||||
NSString *m = [NSString stringWithCString: ms];
|
||||
|
||||
|
||||
if (fullm)
|
||||
{
|
||||
NSArray *names = [locale objectForKey: NSMonthNameArray];
|
||||
|
@ -427,17 +449,17 @@
|
|||
free(newf);
|
||||
|
||||
return [self initWithYear: yd month: md day: dd hour: hd
|
||||
minute: mnd second: sd
|
||||
minute: mnd second: sd
|
||||
timeZone: tz];
|
||||
}
|
||||
|
||||
- (id)initWithYear:(int)year
|
||||
month:(unsigned int)month
|
||||
day:(unsigned int)day
|
||||
hour:(unsigned int)hour
|
||||
minute:(unsigned int)minute
|
||||
second:(unsigned int)second
|
||||
timeZone:(NSTimeZone *)aTimeZone
|
||||
- (id)initWithYear: (int)year
|
||||
month: (unsigned int)month
|
||||
day: (unsigned int)day
|
||||
hour: (unsigned int)hour
|
||||
minute: (unsigned int)minute
|
||||
second: (unsigned int)second
|
||||
timeZone: (NSTimeZone *)aTimeZone
|
||||
{
|
||||
int a;
|
||||
int c;
|
||||
|
@ -463,7 +485,7 @@
|
|||
|
||||
/* Now permit up to five cycles of adjustment to allow for daylight savings.
|
||||
NB. this depends on it being OK to call the
|
||||
[-initWithTimeIntervalSinceReferenceDate:] method repeatedly! */
|
||||
[-initWithTimeIntervalSinceReferenceDate: ] method repeatedly! */
|
||||
|
||||
for (c = 0; c < 5 && self != nil; c++)
|
||||
{
|
||||
|
@ -523,9 +545,9 @@
|
|||
}
|
||||
|
||||
// Default initializer
|
||||
- (id)initWithTimeIntervalSinceReferenceDate:(NSTimeInterval)seconds
|
||||
- (id)initWithTimeIntervalSinceReferenceDate: (NSTimeInterval)seconds
|
||||
{
|
||||
[super initWithTimeIntervalSinceReferenceDate: seconds];
|
||||
seconds_since_ref = seconds;
|
||||
if (!calendar_format)
|
||||
calendar_format = @"%Y-%m-%d %H:%M:%S %z";
|
||||
if (!time_zone)
|
||||
|
@ -534,8 +556,8 @@
|
|||
}
|
||||
|
||||
// Retreiving Date Elements
|
||||
- (void)getYear:(int *)year month:(int *)month day:(int *)day
|
||||
hour:(int *)hour minute:(int *)minute second:(int *)second
|
||||
- (void)getYear: (int *)year month: (int *)month day: (int *)day
|
||||
hour: (int *)hour minute: (int *)minute second: (int *)second
|
||||
{
|
||||
int h, m;
|
||||
double a, b, c, d = [self dayOfCommonEra];
|
||||
|
@ -578,7 +600,7 @@
|
|||
{
|
||||
int m, d, y;
|
||||
|
||||
[self gregorianDateFromAbsolute: [self dayOfCommonEra]
|
||||
[self gregorianDateFromAbsolute: [self dayOfCommonEra]
|
||||
day: &d month: &m year: &y];
|
||||
|
||||
return d;
|
||||
|
@ -691,12 +713,12 @@
|
|||
}
|
||||
|
||||
// Providing Adjusted Dates
|
||||
- (NSCalendarDate *)addYear:(int)year
|
||||
month:(unsigned int)month
|
||||
day:(unsigned int)day
|
||||
hour:(unsigned int)hour
|
||||
minute:(unsigned int)minute
|
||||
second:(unsigned int)second
|
||||
- (NSCalendarDate *)addYear: (int)year
|
||||
month: (unsigned int)month
|
||||
day: (unsigned int)day
|
||||
hour: (unsigned int)hour
|
||||
minute: (unsigned int)minute
|
||||
second: (unsigned int)second
|
||||
{
|
||||
return [self dateByAddingYears: year
|
||||
months: month
|
||||
|
@ -713,15 +735,15 @@
|
|||
locale: nil];
|
||||
}
|
||||
|
||||
- (NSString *)descriptionWithCalendarFormat:(NSString *)format
|
||||
- (NSString *)descriptionWithCalendarFormat: (NSString *)format
|
||||
{
|
||||
return [self descriptionWithCalendarFormat: format
|
||||
locale: nil];
|
||||
}
|
||||
|
||||
#define UNIX_REFERENCE_INTERVAL -978307200.0
|
||||
- (NSString *)descriptionWithCalendarFormat:(NSString *)format
|
||||
locale:(NSDictionary *)locale
|
||||
- (NSString *)descriptionWithCalendarFormat: (NSString *)format
|
||||
locale: (NSDictionary *)locale
|
||||
{
|
||||
char buf[1024];
|
||||
const char *f;
|
||||
|
@ -830,19 +852,19 @@
|
|||
j += k;
|
||||
break;
|
||||
|
||||
case 'd': // day of month
|
||||
case 'd': // day of month
|
||||
++i;
|
||||
k = VSPRINTF_LENGTH(sprintf(&(buf[j]), "%02d", dom));
|
||||
j += k;
|
||||
break;
|
||||
|
||||
case 'e': // day of month
|
||||
case 'e': // day of month
|
||||
++i;
|
||||
k = VSPRINTF_LENGTH(sprintf(&(buf[j]), "%2d", dom));
|
||||
j += k;
|
||||
break;
|
||||
|
||||
case 'F': // milliseconds
|
||||
case 'F': // milliseconds
|
||||
s = ([self dayOfCommonEra] - GREGORIAN_REFERENCE) * 86400.0;
|
||||
s -= (seconds_since_ref+[time_zone timeZoneSecondsFromGMT]);
|
||||
s = abs(s);
|
||||
|
@ -852,7 +874,7 @@
|
|||
j += k;
|
||||
break;
|
||||
|
||||
case 'j': // day of year
|
||||
case 'j': // day of year
|
||||
if (doy < 0) doy = [self dayOfYear];
|
||||
++i;
|
||||
k = VSPRINTF_LENGTH(sprintf(&(buf[j]), "%02d", doy));
|
||||
|
@ -982,12 +1004,12 @@
|
|||
return [NSString stringWithCString: buf];
|
||||
}
|
||||
|
||||
- (id) copyWithZone:(NSZone*)zone
|
||||
- (id) copyWithZone: (NSZone*)zone
|
||||
{
|
||||
NSCalendarDate *newDate;
|
||||
|
||||
if (NSShouldRetainWithZone(self, zone)) {
|
||||
newDate = [self retain];
|
||||
newDate = RETAIN(self);
|
||||
}
|
||||
else {
|
||||
newDate = (NSCalendarDate*)NSCopyObject(self, 0, zone);
|
||||
|
@ -999,7 +1021,7 @@
|
|||
return newDate;
|
||||
}
|
||||
|
||||
- (NSString *)descriptionWithLocale:(NSDictionary *)locale
|
||||
- (NSString *)descriptionWithLocale: (NSDictionary *)locale
|
||||
{
|
||||
return [self descriptionWithCalendarFormat: calendar_format
|
||||
locale: locale];
|
||||
|
@ -1011,14 +1033,14 @@
|
|||
return calendar_format;
|
||||
}
|
||||
|
||||
- (void)setCalendarFormat:(NSString *)format
|
||||
- (void)setCalendarFormat: (NSString *)format
|
||||
{
|
||||
[calendar_format release];
|
||||
RELEASE(calendar_format);
|
||||
calendar_format = [format copyWithZone: [self zone]];
|
||||
}
|
||||
|
||||
// Getting and Setting Time Zones
|
||||
- (void)setTimeZone:(NSTimeZone *)aTimeZone
|
||||
- (void)setTimeZone: (NSTimeZone *)aTimeZone
|
||||
{
|
||||
time_zone = [aTimeZone timeZoneDetailForDate: self];
|
||||
}
|
||||
|
@ -1041,7 +1063,7 @@
|
|||
|
||||
@implementation NSCalendarDate (GregorianDate)
|
||||
|
||||
- (int)lastDayOfGregorianMonth:(int)month year:(int)year
|
||||
- (int)lastDayOfGregorianMonth: (int)month year: (int)year
|
||||
{
|
||||
switch (month) {
|
||||
case 2:
|
||||
|
@ -1058,14 +1080,14 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (int)absoluteGregorianDay:(int)day month:(int)month year:(int)year
|
||||
- (int)absoluteGregorianDay: (int)day month: (int)month year: (int)year
|
||||
{
|
||||
int m, N;
|
||||
|
||||
N = day; // day of month
|
||||
for (m = month - 1; m > 0; m--) // days in prior months this year
|
||||
N = N + [self lastDayOfGregorianMonth: m year: year];
|
||||
return
|
||||
return
|
||||
(N // days this year
|
||||
+ 365 * (year - 1) // days in previous years ignoring leap days
|
||||
+ (year - 1)/4 // Julian leap days before this year...
|
||||
|
@ -1073,10 +1095,10 @@
|
|||
+ (year - 1)/400); // ...plus prior years divisible by 400
|
||||
}
|
||||
|
||||
- (void)gregorianDateFromAbsolute:(int)d
|
||||
day:(int *)day
|
||||
month:(int *)month
|
||||
year:(int *)year
|
||||
- (void)gregorianDateFromAbsolute: (int)d
|
||||
day: (int *)day
|
||||
month: (int *)month
|
||||
year: (int *)year
|
||||
{
|
||||
// Search forward year by year from approximate year
|
||||
*year = d/366;
|
||||
|
@ -1084,7 +1106,7 @@
|
|||
(*year)++;
|
||||
// Search forward month by month from January
|
||||
(*month) = 1;
|
||||
while (d > [self absoluteGregorianDay:
|
||||
while (d > [self absoluteGregorianDay:
|
||||
[self lastDayOfGregorianMonth: *month year: *year]
|
||||
month: *month year: *year])
|
||||
(*month)++;
|
||||
|
@ -1096,12 +1118,12 @@
|
|||
|
||||
@implementation NSCalendarDate (OPENSTEP)
|
||||
|
||||
- (NSCalendarDate *)dateByAddingYears:(int)years
|
||||
months:(int)months
|
||||
days:(int)days
|
||||
hours:(int)hours
|
||||
minutes:(int)minutes
|
||||
seconds:(int)seconds
|
||||
- (NSCalendarDate *)dateByAddingYears: (int)years
|
||||
months: (int)months
|
||||
days: (int)days
|
||||
hours: (int)hours
|
||||
minutes: (int)minutes
|
||||
seconds: (int)seconds
|
||||
{
|
||||
int i, year, month, day, hour, minute, second;
|
||||
|
||||
|
@ -1168,7 +1190,7 @@
|
|||
day += [self lastDayOfGregorianMonth: month year: year];
|
||||
}
|
||||
|
||||
month += months;
|
||||
month += months;
|
||||
while (month > 12)
|
||||
{
|
||||
year++;
|
||||
|
@ -1182,13 +1204,13 @@
|
|||
|
||||
year += years;
|
||||
|
||||
return [NSCalendarDate dateWithYear:year
|
||||
month:month
|
||||
day:day
|
||||
hour:hour
|
||||
minute:minute
|
||||
second:second
|
||||
timeZone:nil];
|
||||
return [NSCalendarDate dateWithYear: year
|
||||
month: month
|
||||
day: day
|
||||
hour: hour
|
||||
minute: minute
|
||||
second: second
|
||||
timeZone: nil];
|
||||
}
|
||||
|
||||
- (void) years: (int*)years
|
||||
|
@ -1212,7 +1234,7 @@
|
|||
How about daylight savings time?
|
||||
*/
|
||||
if ([date isKindOfClass: [NSCalendarDate class]])
|
||||
tmp = (NSCalendarDate*)[date retain];
|
||||
tmp = (NSCalendarDate*)RETAIN(date);
|
||||
else
|
||||
tmp = [[NSCalendarDate alloc] initWithTimeIntervalSinceReferenceDate:
|
||||
[date timeIntervalSinceReferenceDate]];
|
||||
|
@ -1321,7 +1343,7 @@
|
|||
if (seconds)
|
||||
*seconds = sign*diff;
|
||||
|
||||
[tmp release];
|
||||
RELEASE(tmp);
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -297,7 +297,7 @@ static int messages_received_count;
|
|||
NSConnection* c;
|
||||
NSThread* t;
|
||||
|
||||
t = [NSThread currentThread];
|
||||
t = GSCurrentThread();
|
||||
c = (NSConnection*)[[t threadDictionary] objectForKey:tkey];
|
||||
if (c != nil && [c isValid] == NO) {
|
||||
/*
|
||||
|
|
326
Source/NSDate.m
326
Source/NSDate.m
|
@ -23,12 +23,6 @@
|
|||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
1995-03-31 02:41:00 -0600 Jeremy Bettis <jeremy@hksys.com>
|
||||
Release the first draft of NSDate.
|
||||
Three methods not implemented, and NSCalendarDate/NSTimeZone don't exist.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <Foundation/NSArray.h>
|
||||
#include <Foundation/NSDictionary.h>
|
||||
|
@ -39,6 +33,7 @@
|
|||
#include <Foundation/NSUserDefaults.h>
|
||||
#include <Foundation/NSCharacterSet.h>
|
||||
#include <Foundation/NSScanner.h>
|
||||
#include <base/fast.x>
|
||||
#ifndef __WIN32__
|
||||
#include <time.h>
|
||||
#endif /* !__WIN32__ */
|
||||
|
@ -49,7 +44,7 @@
|
|||
#endif /* !__WIN32__ */
|
||||
|
||||
/* The number of seconds between 1/1/2001 and 1/1/1970 = -978307200. */
|
||||
/* This number comes from:
|
||||
/* This number comes from:
|
||||
-(((31 years * 365 days) + 8 days for leap years) =total number of days
|
||||
* 24 hours
|
||||
* 60 minutes
|
||||
|
@ -62,6 +57,12 @@
|
|||
#define DISTANT_FUTURE (DISTANT_YEARS * 365.0 * 24 * 60 * 60)
|
||||
#define DISTANT_PAST (-DISTANT_FUTURE)
|
||||
|
||||
static BOOL debug = NO;
|
||||
static Class abstractClass = nil;
|
||||
static Class concreteClass = nil;
|
||||
static Class calendarClass = nil;
|
||||
|
||||
|
||||
static NSString*
|
||||
findInArray(NSArray *array, unsigned pos, NSString *str)
|
||||
{
|
||||
|
@ -75,20 +76,23 @@ findInArray(NSArray *array, unsigned pos, NSString *str)
|
|||
item = [array objectAtIndex: index];
|
||||
if ([str caseInsensitiveCompare: item] == NSOrderedSame)
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
/* The implementation of NSDate. */
|
||||
static inline NSTimeInterval
|
||||
otherTime(NSDate* other)
|
||||
{
|
||||
Class c = fastClass(other);
|
||||
|
||||
@implementation NSDate
|
||||
if (c == concreteClass || c == calendarClass)
|
||||
return ((NSGDate*)other)->seconds_since_ref;
|
||||
else
|
||||
return [other timeIntervalSinceReferenceDate];
|
||||
}
|
||||
|
||||
static BOOL debug = NO;
|
||||
|
||||
// Getting current time
|
||||
|
||||
+ (NSTimeInterval) timeIntervalSinceReferenceDate
|
||||
static NSTimeInterval
|
||||
timeNow()
|
||||
{
|
||||
#if !defined(__WIN32__) && !defined(_WIN32)
|
||||
volatile NSTimeInterval interval;
|
||||
|
@ -100,7 +104,7 @@ static BOOL debug = NO;
|
|||
interval += (double)tp.tv_usec / 1000000.0;
|
||||
|
||||
/* There seems to be a problem with bad double arithmetic... */
|
||||
NSAssert(interval < 0, NSInternalInconsistencyException);
|
||||
NSCAssert(interval < 0, NSInternalInconsistencyException);
|
||||
|
||||
return interval;
|
||||
#else
|
||||
|
@ -120,17 +124,54 @@ static BOOL debug = NO;
|
|||
minute: sys_time.wMinute
|
||||
second: sys_time.wSecond
|
||||
timeZone: [NSTimeZone localTimeZone]];
|
||||
t = [d timeIntervalSinceReferenceDate];
|
||||
[d release];
|
||||
t = otherTime(d);
|
||||
RELEASE(d);
|
||||
return t + sys_time.wMilliseconds / 1000.0;
|
||||
#endif /* __WIN32__ */
|
||||
}
|
||||
|
||||
/* The implementation of NSDate. */
|
||||
|
||||
@implementation NSDate
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (self == [NSDate class])
|
||||
{
|
||||
[self setVersion: 1];
|
||||
abstractClass = self;
|
||||
concreteClass = [NSGDate class];
|
||||
calendarClass = [NSCalendarDate class];
|
||||
}
|
||||
}
|
||||
|
||||
+ (id) alloc
|
||||
{
|
||||
if (self == abstractClass)
|
||||
return NSAllocateObject(concreteClass, 0, NSDefaultMallocZone());
|
||||
else
|
||||
return NSAllocateObject(self, 0, NSDefaultMallocZone());
|
||||
}
|
||||
|
||||
+ (id) allocWithZone: (NSZone*)z
|
||||
{
|
||||
if (self == abstractClass)
|
||||
return NSAllocateObject(concreteClass, 0, z);
|
||||
else
|
||||
return NSAllocateObject(self, 0, z);
|
||||
}
|
||||
|
||||
+ (NSTimeInterval) timeIntervalSinceReferenceDate
|
||||
{
|
||||
return timeNow();
|
||||
}
|
||||
|
||||
// Allocation and initializing
|
||||
|
||||
+ (id) date
|
||||
{
|
||||
return [[[self alloc] init] autorelease];
|
||||
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
|
||||
initWithTimeIntervalSinceReferenceDate: timeNow()]);
|
||||
}
|
||||
|
||||
+ (id) dateWithNaturalLanguageString: (NSString*)string
|
||||
|
@ -179,7 +220,7 @@ static BOOL debug = NO;
|
|||
scanner = [NSScanner scannerWithString: string];
|
||||
words = [NSMutableArray arrayWithCapacity: 10];
|
||||
|
||||
theDate = (NSCalendarDate*)[NSCalendarDate date];
|
||||
theDate = (NSCalendarDate*)[calendarClass date];
|
||||
Y = [theDate yearOfCommonEra];
|
||||
M = [theDate monthOfYear];
|
||||
D = [theDate dayOfMonth];
|
||||
|
@ -563,21 +604,21 @@ static BOOL debug = NO;
|
|||
else
|
||||
mustSkip = NO;
|
||||
break;
|
||||
|
||||
|
||||
case 'Y':
|
||||
if (hadYear)
|
||||
dtoIndex++;
|
||||
else
|
||||
mustSkip = NO;
|
||||
break;
|
||||
|
||||
|
||||
case 'H':
|
||||
if (hadHour)
|
||||
dtoIndex++;
|
||||
else
|
||||
mustSkip = NO;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
dtoIndex++;
|
||||
if (debug)
|
||||
|
@ -713,12 +754,12 @@ static BOOL debug = NO;
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* If we had no date or time information - we give up, otherwise
|
||||
* we can use reasonable defaults for any missing info.
|
||||
* Missing date => today
|
||||
* Missing time => 12:00
|
||||
* Missing time => 12: 00
|
||||
* If we had a week/month/year modifier without a day, we assume today.
|
||||
* If we had a day name without any more day detail - adjust to that
|
||||
* day this week.
|
||||
|
@ -739,7 +780,7 @@ static BOOL debug = NO;
|
|||
/*
|
||||
* Build a calendar date we can adjust easily.
|
||||
*/
|
||||
theDate = [NSCalendarDate dateWithYear: Y
|
||||
theDate = [calendarClass dateWithYear: Y
|
||||
month: M
|
||||
day: D
|
||||
hour: h
|
||||
|
@ -766,29 +807,28 @@ static BOOL debug = NO;
|
|||
return nil;
|
||||
}
|
||||
return [self dateWithTimeIntervalSinceReferenceDate:
|
||||
[theDate timeIntervalSinceReferenceDate]];
|
||||
otherTime(theDate)];
|
||||
}
|
||||
|
||||
+ (id) dateWithString: (NSString*)description
|
||||
{
|
||||
return [[[self alloc] initWithString: description] autorelease];
|
||||
return AUTORELEASE([[self alloc] initWithString: description]);
|
||||
}
|
||||
|
||||
+ (id) dateWithTimeIntervalSinceNow: (NSTimeInterval)seconds
|
||||
{
|
||||
return [[[self alloc] initWithTimeIntervalSinceNow: seconds] autorelease];
|
||||
return AUTORELEASE([[self alloc] initWithTimeIntervalSinceNow: seconds]);
|
||||
}
|
||||
|
||||
+ (id)dateWithTimeIntervalSince1970:(NSTimeInterval)seconds
|
||||
+ (id)dateWithTimeIntervalSince1970: (NSTimeInterval)seconds
|
||||
{
|
||||
return [[[self alloc] initWithTimeIntervalSinceReferenceDate:
|
||||
UNIX_REFERENCE_INTERVAL + seconds] autorelease];
|
||||
return AUTORELEASE([[self alloc] initWithTimeIntervalSinceReferenceDate:
|
||||
UNIX_REFERENCE_INTERVAL + seconds]);
|
||||
}
|
||||
|
||||
+ (id) dateWithTimeIntervalSinceReferenceDate: (NSTimeInterval)seconds
|
||||
{
|
||||
return [[[self alloc] initWithTimeIntervalSinceReferenceDate: seconds]
|
||||
autorelease];
|
||||
return AUTORELEASE([[self alloc] initWithTimeIntervalSinceReferenceDate: seconds]);
|
||||
}
|
||||
|
||||
+ (id) distantFuture
|
||||
|
@ -807,10 +847,10 @@ static BOOL debug = NO;
|
|||
return dp;
|
||||
}
|
||||
|
||||
- (id) copyWithZone:(NSZone*)zone
|
||||
- (id) copyWithZone: (NSZone*)zone
|
||||
{
|
||||
if (NSShouldRetainWithZone(self, zone))
|
||||
return [self retain];
|
||||
return RETAIN(self);
|
||||
else
|
||||
return NSCopyObject(self, 0, zone);
|
||||
}
|
||||
|
@ -819,73 +859,78 @@ static BOOL debug = NO;
|
|||
{
|
||||
/* Make sure that Connection's always send us bycopy,
|
||||
i.e. as our own class, not a Proxy class. */
|
||||
return [self class];
|
||||
return abstractClass;
|
||||
}
|
||||
|
||||
- (Class) classForPortCoder
|
||||
{
|
||||
return [self class];
|
||||
return abstractClass;
|
||||
}
|
||||
|
||||
- replacementObjectForPortCoder: aRmc
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) encodeWithCoder:(NSCoder*)coder
|
||||
- (void) encodeWithCoder: (NSCoder*)coder
|
||||
{
|
||||
[super encodeWithCoder:coder];
|
||||
[coder encodeValueOfObjCType:@encode(NSTimeInterval) at:&seconds_since_ref];
|
||||
NSTimeInterval interval = [self timeIntervalSinceReferenceDate];
|
||||
|
||||
[coder encodeValueOfObjCType: @encode(NSTimeInterval) at: &interval];
|
||||
}
|
||||
|
||||
- (id) initWithCoder:(NSCoder*)coder
|
||||
- (id) initWithCoder: (NSCoder*)coder
|
||||
{
|
||||
self = [super initWithCoder:coder];
|
||||
[coder decodeValueOfObjCType:@encode(NSTimeInterval) at:&seconds_since_ref];
|
||||
return self;
|
||||
NSTimeInterval interval;
|
||||
id o;
|
||||
|
||||
[coder decodeValueOfObjCType: @encode(NSTimeInterval) at: &interval];
|
||||
o = [[concreteClass alloc] initWithTimeIntervalSinceReferenceDate: interval];
|
||||
[self release];
|
||||
return o;
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
return [self initWithTimeIntervalSinceReferenceDate:
|
||||
[[self class] timeIntervalSinceReferenceDate]];
|
||||
return [self initWithTimeIntervalSinceReferenceDate: timeNow()];
|
||||
}
|
||||
|
||||
- (id) initWithString: (NSString*)description
|
||||
{
|
||||
// Easiest to just have NSCalendarDate do the work for us
|
||||
NSCalendarDate *d = [NSCalendarDate alloc];
|
||||
NSCalendarDate *d = [calendarClass alloc];
|
||||
|
||||
[d initWithString: description];
|
||||
[self initWithTimeIntervalSinceReferenceDate:
|
||||
[d timeIntervalSinceReferenceDate]];
|
||||
[d release];
|
||||
otherTime(d)];
|
||||
RELEASE(d);
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) initWithTimeInterval: (NSTimeInterval)secsToBeAdded
|
||||
sinceDate: (NSDate*)anotherDate;
|
||||
sinceDate: (NSDate*)anotherDate;
|
||||
{
|
||||
// Get the other date's time, add the secs and init thyself
|
||||
return [self initWithTimeIntervalSinceReferenceDate:
|
||||
[anotherDate timeIntervalSinceReferenceDate] + secsToBeAdded];
|
||||
otherTime(anotherDate) + secsToBeAdded];
|
||||
}
|
||||
|
||||
- (id) initWithTimeIntervalSinceNow: (NSTimeInterval)secsToBeAdded;
|
||||
{
|
||||
// Get the current time, add the secs and init thyself
|
||||
return [self initWithTimeIntervalSinceReferenceDate:
|
||||
[[self class] timeIntervalSinceReferenceDate] + secsToBeAdded];
|
||||
timeNow() + secsToBeAdded];
|
||||
}
|
||||
|
||||
- (id)initWithTimeIntervalSince1970:(NSTimeInterval)seconds
|
||||
- (id)initWithTimeIntervalSince1970: (NSTimeInterval)seconds
|
||||
{
|
||||
return [self initWithTimeIntervalSinceReferenceDate:
|
||||
return [self initWithTimeIntervalSinceReferenceDate:
|
||||
UNIX_REFERENCE_INTERVAL + seconds];
|
||||
}
|
||||
|
||||
- (id) initWithTimeIntervalSinceReferenceDate: (NSTimeInterval)secs
|
||||
{
|
||||
[super init];
|
||||
seconds_since_ref = secs;
|
||||
[self subclassResponsibility: _cmd];
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -894,11 +939,11 @@ static BOOL debug = NO;
|
|||
- (NSCalendarDate *) dateWithCalendarFormat: (NSString*)formatString
|
||||
timeZone: (NSTimeZone*)timeZone
|
||||
{
|
||||
NSCalendarDate *d = [NSCalendarDate alloc];
|
||||
[d initWithTimeIntervalSinceReferenceDate: seconds_since_ref];
|
||||
NSCalendarDate *d = [calendarClass alloc];
|
||||
[d initWithTimeIntervalSinceReferenceDate: otherTime(self)];
|
||||
[d setCalendarFormat: formatString];
|
||||
[d setTimeZone: timeZone];
|
||||
return [d autorelease];
|
||||
return AUTORELEASE(d);
|
||||
}
|
||||
|
||||
// Representing dates
|
||||
|
@ -907,10 +952,10 @@ static BOOL debug = NO;
|
|||
{
|
||||
// Easiest to just have NSCalendarDate do the work for us
|
||||
NSString *s;
|
||||
NSCalendarDate *d = [NSCalendarDate alloc];
|
||||
[d initWithTimeIntervalSinceReferenceDate: seconds_since_ref];
|
||||
NSCalendarDate *d = [calendarClass alloc];
|
||||
[d initWithTimeIntervalSinceReferenceDate: otherTime(self)];
|
||||
s = [d description];
|
||||
[d release];
|
||||
RELEASE(d);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -920,10 +965,10 @@ static BOOL debug = NO;
|
|||
{
|
||||
// Easiest to just have NSCalendarDate do the work for us
|
||||
NSString *s;
|
||||
NSCalendarDate *d = [NSCalendarDate alloc];
|
||||
NSCalendarDate *d = [calendarClass alloc];
|
||||
id f;
|
||||
|
||||
[d initWithTimeIntervalSinceReferenceDate: seconds_since_ref];
|
||||
[d initWithTimeIntervalSinceReferenceDate: otherTime(self)];
|
||||
if (!format)
|
||||
f = [d calendarFormat];
|
||||
else
|
||||
|
@ -932,7 +977,7 @@ static BOOL debug = NO;
|
|||
[d setTimeZone: aTimeZone];
|
||||
|
||||
s = [d descriptionWithCalendarFormat: f locale: l];
|
||||
[d release];
|
||||
RELEASE(d);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -940,10 +985,10 @@ static BOOL debug = NO;
|
|||
{
|
||||
// Easiest to just have NSCalendarDate do the work for us
|
||||
NSString *s;
|
||||
NSCalendarDate *d = [NSCalendarDate alloc];
|
||||
[d initWithTimeIntervalSinceReferenceDate: seconds_since_ref];
|
||||
NSCalendarDate *d = [calendarClass alloc];
|
||||
[d initWithTimeIntervalSinceReferenceDate: otherTime(self)];
|
||||
s = [d descriptionWithLocale: locale];
|
||||
[d release];
|
||||
RELEASE(d);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -953,6 +998,119 @@ static BOOL debug = NO;
|
|||
{
|
||||
/* xxx We need to check for overflow? */
|
||||
return [[self class] dateWithTimeIntervalSinceReferenceDate:
|
||||
otherTime(self) + seconds];
|
||||
}
|
||||
|
||||
- (NSTimeInterval) timeIntervalSince1970
|
||||
{
|
||||
return otherTime(self) - UNIX_REFERENCE_INTERVAL;
|
||||
}
|
||||
|
||||
- (NSTimeInterval) timeIntervalSinceDate: (NSDate*)otherDate
|
||||
{
|
||||
return otherTime(self) - otherTime(otherDate);
|
||||
}
|
||||
|
||||
- (NSTimeInterval) timeIntervalSinceNow
|
||||
{
|
||||
return otherTime(self) - timeNow();
|
||||
}
|
||||
|
||||
- (NSTimeInterval) timeIntervalSinceReferenceDate
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Comparing dates
|
||||
|
||||
- (NSComparisonResult) compare: (NSDate*)otherDate
|
||||
{
|
||||
if (otherTime(self) > otherTime(otherDate))
|
||||
return NSOrderedDescending;
|
||||
|
||||
if (otherTime(self) < otherTime(otherDate))
|
||||
return NSOrderedAscending;
|
||||
|
||||
return NSOrderedSame;
|
||||
}
|
||||
|
||||
- (NSDate*) earlierDate: (NSDate*)otherDate
|
||||
{
|
||||
if (otherTime(self) > otherTime(otherDate))
|
||||
return otherDate;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL) isEqual: (id)other
|
||||
{
|
||||
if ([other isKindOf: abstractClass]
|
||||
&& 1.0 > ABS(otherTime(self) - otherTime(other)))
|
||||
return YES;
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL) isEqualToDate: (NSDate*)other
|
||||
{
|
||||
if (1.0 > ABS(otherTime(self) - otherTime(other)))
|
||||
return YES;
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSDate*) laterDate: (NSDate*)otherDate
|
||||
{
|
||||
if (otherTime(self)
|
||||
< otherTime(otherDate))
|
||||
return otherDate;
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSGDate
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (self == [NSDate class])
|
||||
{
|
||||
[self setVersion: 1];
|
||||
}
|
||||
}
|
||||
|
||||
- (Class) classForPortCoder
|
||||
{
|
||||
return [self class];
|
||||
}
|
||||
|
||||
- replacementObjectForPortCoder: aRmc
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) encodeWithCoder: (NSCoder*)coder
|
||||
{
|
||||
[coder encodeValueOfObjCType: @encode(NSTimeInterval) at: &seconds_since_ref];
|
||||
}
|
||||
|
||||
- (id) initWithCoder: (NSCoder*)coder
|
||||
{
|
||||
[coder decodeValueOfObjCType: @encode(NSTimeInterval) at: &seconds_since_ref];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) initWithTimeIntervalSinceReferenceDate: (NSTimeInterval)secs
|
||||
{
|
||||
seconds_since_ref = secs;
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
// Adding and getting intervals
|
||||
|
||||
- (id) addTimeInterval: (NSTimeInterval)seconds
|
||||
{
|
||||
/* xxx We need to check for overflow? */
|
||||
return [concreteClass dateWithTimeIntervalSinceReferenceDate:
|
||||
seconds_since_ref + seconds];
|
||||
}
|
||||
|
||||
|
@ -963,13 +1121,12 @@ static BOOL debug = NO;
|
|||
|
||||
- (NSTimeInterval) timeIntervalSinceDate: (NSDate*)otherDate
|
||||
{
|
||||
return seconds_since_ref - [otherDate timeIntervalSinceReferenceDate];
|
||||
return seconds_since_ref - otherTime(otherDate);
|
||||
}
|
||||
|
||||
- (NSTimeInterval) timeIntervalSinceNow
|
||||
{
|
||||
NSTimeInterval now = [[self class] timeIntervalSinceReferenceDate];
|
||||
return seconds_since_ref - now;
|
||||
return seconds_since_ref - timeNow();
|
||||
}
|
||||
|
||||
- (NSTimeInterval) timeIntervalSinceReferenceDate
|
||||
|
@ -981,42 +1138,43 @@ static BOOL debug = NO;
|
|||
|
||||
- (NSComparisonResult) compare: (NSDate*)otherDate
|
||||
{
|
||||
if (seconds_since_ref > [otherDate timeIntervalSinceReferenceDate])
|
||||
if (seconds_since_ref > otherTime(otherDate))
|
||||
return NSOrderedDescending;
|
||||
|
||||
if (seconds_since_ref < [otherDate timeIntervalSinceReferenceDate])
|
||||
|
||||
if (seconds_since_ref < otherTime(otherDate))
|
||||
return NSOrderedAscending;
|
||||
|
||||
|
||||
return NSOrderedSame;
|
||||
}
|
||||
|
||||
- (NSDate*) earlierDate: (NSDate*)otherDate
|
||||
{
|
||||
if (seconds_since_ref > [otherDate timeIntervalSinceReferenceDate])
|
||||
if (seconds_since_ref > otherTime(otherDate))
|
||||
return otherDate;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL) isEqual: (id)other
|
||||
{
|
||||
if ([other isKindOf: [NSDate class]]
|
||||
&& 1.0 > ABS(seconds_since_ref - [other timeIntervalSinceReferenceDate]))
|
||||
if ([other isKindOfClass: abstractClass]
|
||||
&& 1.0 > ABS(seconds_since_ref - otherTime(other)))
|
||||
return YES;
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL) isEqualToDate: (NSDate*)other
|
||||
{
|
||||
if (1.0 > ABS(seconds_since_ref - [other timeIntervalSinceReferenceDate]))
|
||||
if (1.0 > ABS(seconds_since_ref - otherTime(other)))
|
||||
return YES;
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSDate*) laterDate: (NSDate*)otherDate
|
||||
{
|
||||
if (seconds_since_ref < [otherDate timeIntervalSinceReferenceDate])
|
||||
if (seconds_since_ref < otherTime(otherDate))
|
||||
return otherDate;
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ typedef struct {
|
|||
Class class;
|
||||
int count;
|
||||
int lastc;
|
||||
int total;
|
||||
} table_entry;
|
||||
|
||||
static int num_classes = 0;
|
||||
|
@ -73,6 +74,7 @@ GSDebugAllocationAdd(Class c)
|
|||
if (the_table[i].class == c)
|
||||
{
|
||||
the_table[i].count++;
|
||||
the_table[i].total++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -95,6 +97,7 @@ GSDebugAllocationAdd(Class c)
|
|||
the_table[num_classes].class = c;
|
||||
the_table[num_classes].count = 1;
|
||||
the_table[num_classes].lastc = 0;
|
||||
the_table[num_classes].total = 1;
|
||||
num_classes++;
|
||||
}
|
||||
}
|
||||
|
@ -138,7 +141,11 @@ GSDebugAllocationList(BOOL difference)
|
|||
|
||||
if (difference)
|
||||
{
|
||||
#if 1
|
||||
val = the_table[i].total;
|
||||
#else
|
||||
val -= the_table[i].lastc;
|
||||
#endif
|
||||
}
|
||||
if (val != 0)
|
||||
{
|
||||
|
@ -181,7 +188,11 @@ GSDebugAllocationList(BOOL difference)
|
|||
|
||||
if (difference)
|
||||
{
|
||||
#if 1
|
||||
val = the_table[i].total;
|
||||
#else
|
||||
val -= the_table[i].lastc;
|
||||
#endif
|
||||
}
|
||||
the_table[i].lastc = the_table[i].count;
|
||||
|
||||
|
@ -195,6 +206,64 @@ GSDebugAllocationList(BOOL difference)
|
|||
return buf;
|
||||
}
|
||||
|
||||
const char*
|
||||
GSDebugAllocationListAll()
|
||||
{
|
||||
int pos = 0;
|
||||
int i;
|
||||
static int siz = 0;
|
||||
static char *buf = 0;
|
||||
|
||||
if (debug_allocation == NO)
|
||||
{
|
||||
return "Debug allocation system is not active!\n";
|
||||
}
|
||||
for (i = 0; i < num_classes; i++)
|
||||
{
|
||||
int val = the_table[i].total;
|
||||
|
||||
if (val != 0)
|
||||
{
|
||||
pos += 11 + strlen(the_table[i].class->name);
|
||||
}
|
||||
}
|
||||
if (pos == 0)
|
||||
{
|
||||
return "I can find NO allocated object!\n";
|
||||
}
|
||||
pos++;
|
||||
|
||||
if (pos > siz)
|
||||
{
|
||||
if (pos & 0xff)
|
||||
{
|
||||
pos = ((pos >> 8) + 1) << 8;
|
||||
}
|
||||
siz = pos;
|
||||
if (buf)
|
||||
{
|
||||
objc_free(buf);
|
||||
}
|
||||
buf = objc_malloc(siz);
|
||||
}
|
||||
|
||||
if (buf)
|
||||
{
|
||||
pos = 0;
|
||||
for (i = 0; i < num_classes; i++)
|
||||
{
|
||||
int val = the_table[i].total;
|
||||
|
||||
if (val != 0)
|
||||
{
|
||||
sprintf(&buf[pos], "%s\t%d\n", the_table[i].class->name, val);
|
||||
pos += strlen(&buf[pos]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
void
|
||||
GSDebugAllocationRemove(Class c)
|
||||
{
|
||||
|
|
|
@ -108,7 +108,7 @@ _NSFoundationUncaughtExceptionHandler(NSException *exception)
|
|||
if (_NSUncaughtExceptionHandler == NULL)
|
||||
_NSUncaughtExceptionHandler = _NSFoundationUncaughtExceptionHandler;
|
||||
|
||||
thread = [NSThread currentThread];
|
||||
thread = GSCurrentThread();
|
||||
handler = thread->_exception_handler;
|
||||
if (handler == NULL) {
|
||||
_NSUncaughtExceptionHandler(self);
|
||||
|
@ -185,18 +185,18 @@ _NSFoundationUncaughtExceptionHandler(NSException *exception)
|
|||
void
|
||||
_NSAddHandler( NSHandler *handler )
|
||||
{
|
||||
NSThread *thread;
|
||||
NSThread *thread;
|
||||
|
||||
thread = [NSThread currentThread];
|
||||
handler->next = thread->_exception_handler;
|
||||
thread->_exception_handler = handler;
|
||||
thread = GSCurrentThread();
|
||||
handler->next = thread->_exception_handler;
|
||||
thread->_exception_handler = handler;
|
||||
}
|
||||
|
||||
void
|
||||
_NSRemoveHandler( NSHandler *handler )
|
||||
{
|
||||
NSThread *thread;
|
||||
NSThread *thread;
|
||||
|
||||
thread = [NSThread currentThread];
|
||||
thread->_exception_handler = thread->_exception_handler->next;
|
||||
thread = GSCurrentThread();
|
||||
thread->_exception_handler = thread->_exception_handler->next;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ typedef struct {
|
|||
unsigned _hash;
|
||||
} *dictAccessToStringHack;
|
||||
|
||||
static INLINE unsigned
|
||||
static inline unsigned
|
||||
myHash(id obj)
|
||||
{
|
||||
if (fastIsInstance(obj))
|
||||
|
@ -68,7 +68,7 @@ myHash(id obj)
|
|||
return [obj hash];
|
||||
}
|
||||
|
||||
static INLINE BOOL
|
||||
static inline BOOL
|
||||
myEqual(id self, id other)
|
||||
{
|
||||
if (self == other)
|
||||
|
|
|
@ -51,6 +51,16 @@
|
|||
|
||||
@implementation NSGSequence
|
||||
|
||||
static Class seqClass;
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (self == [NSGSequence class])
|
||||
{
|
||||
seqClass = self;
|
||||
}
|
||||
}
|
||||
|
||||
// Creating Temporary Sequences
|
||||
|
||||
+ (NSGSequence*) sequenceWithString: (NSString*) aString
|
||||
|
@ -194,11 +204,15 @@
|
|||
- (void) getCharacters: (unichar*)buffer
|
||||
range: (NSRange)aRange
|
||||
{
|
||||
#if 0
|
||||
int i;
|
||||
for (i = 0; i < aRange.length; i++)
|
||||
{
|
||||
buffer[i] = [self characterAtIndex: aRange.location+i];
|
||||
}
|
||||
#else
|
||||
memcpy(buffer, &_contents_chars[aRange.location], aRange.length*2);
|
||||
#endif
|
||||
}
|
||||
|
||||
//for debuging
|
||||
|
@ -357,7 +371,7 @@
|
|||
for(count=0;count<len;count++)
|
||||
s[count]=uni_tolower(_contents_chars[count]);
|
||||
s[len] = (unichar)0;
|
||||
return [NSGSequence sequenceWithCharactersNoCopy:s length:len freeWhenDone:YES];
|
||||
return [seqClass sequenceWithCharactersNoCopy:s length:len freeWhenDone:YES];
|
||||
}
|
||||
|
||||
- (NSGSequence*) uppercase
|
||||
|
@ -369,7 +383,7 @@
|
|||
for(count=0;count<len;count++)
|
||||
s[count]=uni_toupper(_contents_chars[count]);
|
||||
s[len] = (unichar)0;
|
||||
return [NSGSequence sequenceWithCharactersNoCopy:s length:len freeWhenDone:YES];
|
||||
return [seqClass sequenceWithCharactersNoCopy:s length:len freeWhenDone:YES];
|
||||
}
|
||||
|
||||
- (NSGSequence*) titlecase
|
||||
|
@ -397,8 +411,15 @@
|
|||
end=seqLength;
|
||||
for (i = 0; i < end; i ++)
|
||||
{
|
||||
#if 0
|
||||
if ([self characterAtIndex:i] < [aSequence characterAtIndex:i]) return NSOrderedAscending;
|
||||
if ([self characterAtIndex:i] > [aSequence characterAtIndex:i]) return NSOrderedDescending;
|
||||
#else
|
||||
if (_contents_chars[i] < aSequence->_contents_chars[i])
|
||||
return NSOrderedAscending;
|
||||
if (_contents_chars[i] > aSequence->_contents_chars[i])
|
||||
return NSOrderedDescending;
|
||||
#endif
|
||||
}
|
||||
if(myLength<seqLength)
|
||||
return NSOrderedAscending;
|
||||
|
|
|
@ -81,7 +81,7 @@ static NSString* tkey = @"NotificationQueueListThreadKey";
|
|||
NotificationQueueList* list;
|
||||
NSThread* t;
|
||||
|
||||
t = [NSThread currentThread];
|
||||
t = GSCurrentThread();
|
||||
list = (NotificationQueueList*)[[t threadDictionary] objectForKey:tkey];
|
||||
if (list == nil)
|
||||
{
|
||||
|
@ -129,7 +129,7 @@ static NSString* tkey = @"NotificationQueueListThreadKey";
|
|||
{
|
||||
NSThread* t;
|
||||
|
||||
t = [NSThread currentThread];
|
||||
t = GSCurrentThread();
|
||||
if (list->next)
|
||||
{
|
||||
NotificationQueueList* tmp = list->next;
|
||||
|
|
|
@ -72,7 +72,10 @@
|
|||
#include <limits.h>
|
||||
#include <string.h> /* for memset() */
|
||||
|
||||
static int debug_run_loop = 0;
|
||||
static int debug_run_loop = 0;
|
||||
|
||||
static SEL isValidSel = @selector(isValid);
|
||||
|
||||
|
||||
/*
|
||||
* The 'RunLoopWatcher' class was written to permit the (relatively)
|
||||
|
@ -93,7 +96,7 @@ static int debug_run_loop = 0;
|
|||
* to exist and can handle a callback.
|
||||
*
|
||||
* The 'type' variable indentifies the type of event watched for.
|
||||
* NSRunLoops [-acceptInputForMode:beforeDate:] method MUST contain
|
||||
* NSRunLoops [-acceptInputForMode: beforeDate: ] method MUST contain
|
||||
* code to watch for events of each type.
|
||||
*
|
||||
* The 'limit' variable contains a date after which the event is useless
|
||||
|
@ -102,7 +105,7 @@ static int debug_run_loop = 0;
|
|||
*
|
||||
* To set this variable, the method adding the RunLoopWatcher to the
|
||||
* runloop must ask the 'receiver' (or its delegate) to supply a date
|
||||
* using the '[-limitDateForMode:]' message.
|
||||
* using the '[-limitDateForMode: ]' message.
|
||||
*
|
||||
* NB. This class is private to NSRunLoop and must not be subclassed.
|
||||
*/
|
||||
|
@ -112,6 +115,7 @@ static int debug_run_loop = 0;
|
|||
@public
|
||||
BOOL invalidated;
|
||||
BOOL handleEvent; // New-style event handling
|
||||
BOOL (*handleIsValid)();
|
||||
void *data;
|
||||
id receiver;
|
||||
RunLoopEventType type;
|
||||
|
@ -153,12 +157,12 @@ static int debug_run_loop = 0;
|
|||
{
|
||||
switch (type)
|
||||
{
|
||||
case ET_RDESC:
|
||||
case ET_RPORT:
|
||||
case ET_RDESC:
|
||||
case ET_RPORT:
|
||||
[receiver readyForReadingOnFileDescriptor: (int)(gsaddr)info];
|
||||
break;
|
||||
|
||||
case ET_WDESC:
|
||||
case ET_WDESC:
|
||||
[receiver readyForWritingOnFileDescriptor: (int)(gsaddr)info];
|
||||
break;
|
||||
}
|
||||
|
@ -178,20 +182,22 @@ static int debug_run_loop = 0;
|
|||
|
||||
switch (aType)
|
||||
{
|
||||
case ET_RDESC: type = aType; break;
|
||||
case ET_WDESC: type = aType; break;
|
||||
case ET_RPORT: type = aType; break;
|
||||
default:
|
||||
case ET_RDESC: type = aType; break;
|
||||
case ET_WDESC: type = aType; break;
|
||||
case ET_RPORT: type = aType; break;
|
||||
default:
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSRunLoop - unknown event type"];
|
||||
}
|
||||
receiver = RETAIN(anObj);
|
||||
if ([receiver respondsToSelector:
|
||||
if ([receiver respondsToSelector:
|
||||
@selector(receivedEvent:type:extra:forMode:)])
|
||||
handleEvent = YES;
|
||||
else
|
||||
handleEvent = NO;
|
||||
data = item;
|
||||
if ([receiver respondsToSelector: isValidSel])
|
||||
handleIsValid = (BOOL(*)())[receiver methodForSelector: isValidSel];
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -206,8 +212,7 @@ static int debug_run_loop = 0;
|
|||
{
|
||||
return NO;
|
||||
}
|
||||
if ([receiver respondsToSelector: @selector(isValid)] &&
|
||||
[receiver isValid] == NO)
|
||||
if (handleIsValid != 0 && (*handleIsValid)(receiver, isValidSel) == NO)
|
||||
{
|
||||
[self invalidate];
|
||||
return NO;
|
||||
|
@ -313,7 +318,7 @@ static int debug_run_loop = 0;
|
|||
{
|
||||
if (target == aTarget)
|
||||
{
|
||||
if ([argument isEqual:anArgument])
|
||||
if ([argument isEqual: anArgument])
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
@ -450,7 +455,7 @@ static int debug_run_loop = 0;
|
|||
NSDate *limit;
|
||||
int count;
|
||||
|
||||
watchers = NSMapGet (_mode_2_watchers, mode);
|
||||
watchers = NSMapGet(_mode_2_watchers, mode);
|
||||
if (watchers == nil)
|
||||
{
|
||||
watchers = [NSMutableArray new];
|
||||
|
@ -465,7 +470,7 @@ static int debug_run_loop = 0;
|
|||
|
||||
/*
|
||||
* If the receiver or its delegate (if any) respond to
|
||||
* 'limitDateForMode:' then we ask them for the limit date for
|
||||
* 'limitDateForMode: ' then we ask them for the limit date for
|
||||
* this watcher.
|
||||
*/
|
||||
obj = item->receiver;
|
||||
|
@ -492,7 +497,7 @@ static int debug_run_loop = 0;
|
|||
*/
|
||||
if (limit == nil || count == 0)
|
||||
{
|
||||
[watchers addObject:item];
|
||||
[watchers addObject: item];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -503,15 +508,15 @@ static int debug_run_loop = 0;
|
|||
RunLoopWatcher *watcher = [watchers objectAtIndex: i];
|
||||
NSDate *when = watcher->limit;
|
||||
|
||||
if (when == nil || [limit earlierDate:when] == when)
|
||||
if (when == nil || [limit earlierDate: when] == when)
|
||||
{
|
||||
[watchers insertObject:item atIndex:i];
|
||||
[watchers insertObject: item atIndex: i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == count)
|
||||
{
|
||||
[watchers addObject:item];
|
||||
[watchers addObject: item];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -607,7 +612,7 @@ static int debug_run_loop = 0;
|
|||
receiver: watcher
|
||||
data: data];
|
||||
/* Add the object to the array for the mode. */
|
||||
[self _addWatcher:info forMode:mode];
|
||||
[self _addWatcher: info forMode: mode];
|
||||
RELEASE(info); /* Now held in array. */
|
||||
}
|
||||
}
|
||||
|
@ -669,13 +674,13 @@ static int debug_run_loop = 0;
|
|||
- (void) removeReadDescriptor: (int)fd
|
||||
forMode: (NSString*)mode
|
||||
{
|
||||
return [self removeEvent:(void*)fd type: ET_RDESC forMode:mode all:NO];
|
||||
return [self removeEvent: (void*)fd type: ET_RDESC forMode: mode all: NO];
|
||||
}
|
||||
|
||||
- (void) removeWriteDescriptor: (int)fd
|
||||
forMode: (NSString*)mode
|
||||
{
|
||||
return [self removeEvent:(void*)fd type: ET_WDESC forMode:mode all:NO];
|
||||
return [self removeEvent: (void*)fd type: ET_WDESC forMode: mode all: NO];
|
||||
}
|
||||
|
||||
- (BOOL) runOnceBeforeDate: date
|
||||
|
@ -687,7 +692,7 @@ static int debug_run_loop = 0;
|
|||
|
||||
- (BOOL) runOnceBeforeDate: date forMode: (NSString*)mode
|
||||
{
|
||||
return [self runMode:mode beforeDate:date];
|
||||
return [self runMode: mode beforeDate: date];
|
||||
}
|
||||
|
||||
- (void) runUntilDate: date forMode: (NSString*)mode
|
||||
|
@ -715,27 +720,64 @@ static int debug_run_loop = 0;
|
|||
|
||||
@implementation NSRunLoop
|
||||
|
||||
+ (NSRunLoop*) currentRunLoop
|
||||
{
|
||||
static NSString *key = @"NSRunLoopThreadKey";
|
||||
NSRunLoop* r;
|
||||
NSThread* t;
|
||||
static NSDate *theFuture;
|
||||
|
||||
t = [NSThread currentThread];
|
||||
r = [[t threadDictionary] objectForKey: key];
|
||||
if (r == nil)
|
||||
{
|
||||
r = [NSRunLoop new];
|
||||
[[t threadDictionary] setObject: r forKey: key];
|
||||
RELEASE(r);
|
||||
}
|
||||
return r;
|
||||
#if GS_WITH_GC == 0
|
||||
static SEL wRelSel = @selector(release);
|
||||
static SEL wRetSel = @selector(retain);
|
||||
static IMP wRelImp;
|
||||
static IMP wRetImp;
|
||||
|
||||
static void
|
||||
wRelease(void* t, id w)
|
||||
{
|
||||
(*wRelImp)(w, wRelSel);
|
||||
}
|
||||
|
||||
static id
|
||||
wRetain(void* t, id w)
|
||||
{
|
||||
return (*wRetImp)(w, wRetSel);
|
||||
}
|
||||
|
||||
const NSMapTableValueCallBacks WatcherMapValueCallBacks =
|
||||
{
|
||||
(NSMT_retain_func_t) wRetain,
|
||||
(NSMT_release_func_t) wRelease,
|
||||
(NSMT_describe_func_t) 0
|
||||
};
|
||||
#else
|
||||
#define WatcherMapValueCallBacks NSOwnedPointerMapValueCallBacks
|
||||
#endif
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (self == [NSRunLoop class])
|
||||
[self currentRunLoop];
|
||||
{
|
||||
[self currentRunLoop];
|
||||
theFuture = RETAIN([NSDate distantFuture]);
|
||||
#if GS_WITH_GC == 0
|
||||
wRelImp = [[RunLoopWatcher class] instanceMethodForSelector: wRelSel];
|
||||
wRetImp = [[RunLoopWatcher class] instanceMethodForSelector: wRetSel];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSRunLoop*) currentRunLoop
|
||||
{
|
||||
static NSString *key = @"NSRunLoopThreadKey";
|
||||
NSMutableDictionary *d;
|
||||
NSRunLoop* r;
|
||||
|
||||
d = GSCurrentThreadDictionary();
|
||||
r = [d objectForKey: key];
|
||||
if (r == nil)
|
||||
{
|
||||
r = [NSRunLoop new];
|
||||
[d setObject: r forKey: key];
|
||||
RELEASE(r);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/* This is the designated initializer. */
|
||||
|
@ -747,8 +789,12 @@ static int debug_run_loop = 0;
|
|||
NSObjectMapValueCallBacks, 0);
|
||||
_mode_2_watchers = NSCreateMapTable (NSObjectMapKeyCallBacks,
|
||||
NSObjectMapValueCallBacks, 0);
|
||||
_performers = [[NSMutableArray alloc] initWithCapacity:8];
|
||||
_timedPerformers = [[NSMutableArray alloc] initWithCapacity:8];
|
||||
_performers = [[NSMutableArray alloc] initWithCapacity: 8];
|
||||
_timedPerformers = [[NSMutableArray alloc] initWithCapacity: 8];
|
||||
_rfdMap = NSCreateMapTable (NSIntMapKeyCallBacks,
|
||||
WatcherMapValueCallBacks, 0);
|
||||
_wfdMap = NSCreateMapTable (NSIntMapKeyCallBacks,
|
||||
WatcherMapValueCallBacks, 0);
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -764,6 +810,8 @@ static int debug_run_loop = 0;
|
|||
{
|
||||
NSFreeMapTable(_mode_2_timers);
|
||||
NSFreeMapTable(_mode_2_watchers);
|
||||
NSFreeMapTable(_rfdMap);
|
||||
NSFreeMapTable(_wfdMap);
|
||||
}
|
||||
|
||||
- (NSString*) currentMode
|
||||
|
@ -779,11 +827,11 @@ static int debug_run_loop = 0;
|
|||
{
|
||||
Heap *timers;
|
||||
|
||||
timers = NSMapGet (_mode_2_timers, mode);
|
||||
timers = NSMapGet(_mode_2_timers, mode);
|
||||
if (!timers)
|
||||
{
|
||||
timers = [Heap new];
|
||||
NSMapInsert (_mode_2_timers, mode, timers);
|
||||
NSMapInsert(_mode_2_timers, mode, timers);
|
||||
RELEASE(timers);
|
||||
}
|
||||
/* xxx Should we make sure it isn't already there? */
|
||||
|
@ -844,7 +892,7 @@ static int debug_run_loop = 0;
|
|||
{
|
||||
while ([watchers count] > 0)
|
||||
{
|
||||
min_watcher = (RunLoopWatcher*)[watchers objectAtIndex:0];
|
||||
min_watcher = (RunLoopWatcher*)[watchers objectAtIndex: 0];
|
||||
|
||||
if (![min_watcher isValid])
|
||||
{
|
||||
|
@ -869,17 +917,17 @@ static int debug_run_loop = 0;
|
|||
* revised limit date.
|
||||
*/
|
||||
obj = min_watcher->receiver;
|
||||
if ([obj respondsToSelector:
|
||||
if ([obj respondsToSelector:
|
||||
@selector(timedOutEvent:type:forMode:)])
|
||||
{
|
||||
nxt = [obj timedOutEvent: min_watcher->data
|
||||
type: min_watcher->type
|
||||
forMode: _current_mode];
|
||||
}
|
||||
else if ([obj respondsToSelector:@selector(delegate)])
|
||||
else if ([obj respondsToSelector: @selector(delegate)])
|
||||
{
|
||||
obj = [obj delegate];
|
||||
if ([obj respondsToSelector:
|
||||
if ([obj respondsToSelector:
|
||||
@selector(timedOutEvent:type:forMode:)])
|
||||
{
|
||||
nxt = [obj timedOutEvent: min_watcher->data
|
||||
|
@ -907,7 +955,7 @@ static int debug_run_loop = 0;
|
|||
* check it again.
|
||||
*/
|
||||
[min_watcher invalidate];
|
||||
[watchers removeObjectAtIndex:0];
|
||||
[watchers removeObjectAtIndex: 0];
|
||||
}
|
||||
min_watcher = nil;
|
||||
}
|
||||
|
@ -939,7 +987,7 @@ static int debug_run_loop = 0;
|
|||
|
||||
if (min_watcher->limit == nil) /* No limit for watcher */
|
||||
{
|
||||
lim = [NSDate distantFuture]; /* - watches forever. */
|
||||
lim = theFuture; /* - watches forever. */
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -952,7 +1000,7 @@ static int debug_run_loop = 0;
|
|||
}
|
||||
else
|
||||
{
|
||||
when = [when earlierDate:lim];
|
||||
when = [when earlierDate: lim];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -983,7 +1031,7 @@ static int debug_run_loop = 0;
|
|||
mode = _current_mode;
|
||||
}
|
||||
|
||||
watchers = NSMapGet (_mode_2_watchers, mode);
|
||||
watchers = NSMapGet(_mode_2_watchers, mode);
|
||||
if (watchers == nil)
|
||||
{
|
||||
return nil;
|
||||
|
@ -1014,7 +1062,7 @@ static int debug_run_loop = 0;
|
|||
mode = _current_mode;
|
||||
}
|
||||
|
||||
watchers = NSMapGet (_mode_2_watchers, mode);
|
||||
watchers = NSMapGet(_mode_2_watchers, mode);
|
||||
if (watchers)
|
||||
{
|
||||
int i;
|
||||
|
@ -1023,7 +1071,7 @@ static int debug_run_loop = 0;
|
|||
{
|
||||
RunLoopWatcher* info;
|
||||
|
||||
info = (RunLoopWatcher*)[watchers objectAtIndex:(i-1)];
|
||||
info = (RunLoopWatcher*)[watchers objectAtIndex: (i-1)];
|
||||
if (info->type == type && info->data == data)
|
||||
{
|
||||
[info invalidate];
|
||||
|
@ -1051,8 +1099,6 @@ static int debug_run_loop = 0;
|
|||
fd_set write_fds; /* Copy for listening for write-ready fds. */
|
||||
int select_return;
|
||||
int fd_index;
|
||||
NSMapTable *rfd_2_object;
|
||||
NSMapTable *wfd_2_object;
|
||||
id saved_mode;
|
||||
int num_inputs = 0;
|
||||
|
||||
|
@ -1068,8 +1114,8 @@ static int debug_run_loop = 0;
|
|||
timeout.tv_usec = 0;
|
||||
select_timeout = &timeout;
|
||||
}
|
||||
else if ((ti = [limit_date timeIntervalSinceNow]) < LONG_MAX
|
||||
&& ti > 0.0)
|
||||
else if ((ti = [limit_date timeIntervalSinceNow])
|
||||
< LONG_MAX && ti > 0.0)
|
||||
{
|
||||
/* Wait until the LIMIT_DATE. */
|
||||
if (debug_run_loop)
|
||||
|
@ -1103,27 +1149,29 @@ static int debug_run_loop = 0;
|
|||
select_timeout = NULL;
|
||||
}
|
||||
|
||||
/* Get ready to listen to file descriptors.
|
||||
Initialize the set of FDS we'll pass to select(), and create
|
||||
an empty map for keeping track of which object is associated
|
||||
with which file descriptor. */
|
||||
/*
|
||||
* Get ready to listen to file descriptors.
|
||||
* Initialize the set of FDS we'll pass to select(), and make sure we
|
||||
* have empty maps for keeping track of which watcher is associated
|
||||
* with which file descriptor.
|
||||
* The maps may not have been emptied if a previous call to this
|
||||
* method was terminated by an exception.
|
||||
*/
|
||||
memset(&fds, '\0', sizeof(fds));
|
||||
memset(&write_fds, '\0', sizeof(write_fds));
|
||||
rfd_2_object = NSCreateMapTable (NSIntMapKeyCallBacks,
|
||||
NSObjectMapValueCallBacks, 0);
|
||||
wfd_2_object = NSCreateMapTable (NSIntMapKeyCallBacks,
|
||||
NSObjectMapValueCallBacks, 0);
|
||||
NSResetMapTable(_rfdMap);
|
||||
NSResetMapTable(_wfdMap);
|
||||
|
||||
/* Do the pre-listening set-up for the file descriptors of this mode. */
|
||||
{
|
||||
NSMutableArray *watchers;
|
||||
|
||||
watchers = NSMapGet (_mode_2_watchers, mode);
|
||||
watchers = NSMapGet(_mode_2_watchers, mode);
|
||||
if (watchers) {
|
||||
int i;
|
||||
|
||||
for (i = [watchers count]; i > 0; i--) {
|
||||
RunLoopWatcher* info = [watchers objectAtIndex:(i-1)];
|
||||
RunLoopWatcher* info = [watchers objectAtIndex: (i-1)];
|
||||
int fd;
|
||||
|
||||
if ([info isValid] == NO) {
|
||||
|
@ -1131,21 +1179,21 @@ static int debug_run_loop = 0;
|
|||
continue;
|
||||
}
|
||||
switch (info->type) {
|
||||
case ET_WDESC:
|
||||
case ET_WDESC:
|
||||
fd = (int)info->data;
|
||||
FD_SET (fd, &write_fds);
|
||||
NSMapInsert (wfd_2_object, (void*)fd, info);
|
||||
NSMapInsert(_wfdMap, (void*)fd, info);
|
||||
num_inputs++;
|
||||
break;
|
||||
|
||||
case ET_RDESC:
|
||||
case ET_RDESC:
|
||||
fd = (int)info->data;
|
||||
FD_SET (fd, &fds);
|
||||
NSMapInsert (rfd_2_object, (void*)fd, info);
|
||||
NSMapInsert(_rfdMap, (void*)fd, info);
|
||||
num_inputs++;
|
||||
break;
|
||||
|
||||
case ET_RPORT:
|
||||
case ET_RPORT:
|
||||
{
|
||||
id port = info->receiver;
|
||||
int port_fd_count = 128; // xxx #define this constant
|
||||
|
@ -1160,7 +1208,7 @@ static int debug_run_loop = 0;
|
|||
while (port_fd_count--)
|
||||
{
|
||||
FD_SET (port_fd_array[port_fd_count], &fds);
|
||||
NSMapInsert (rfd_2_object,
|
||||
NSMapInsert(_rfdMap,
|
||||
(void*)port_fd_array[port_fd_count],
|
||||
info);
|
||||
num_inputs++;
|
||||
|
@ -1204,42 +1252,50 @@ static int debug_run_loop = 0;
|
|||
/* Some exceptional condition happened. */
|
||||
/* xxx We can do something with exception_fds, instead of
|
||||
aborting here. */
|
||||
perror ("[NSRunLoop acceptInputForMode:beforeDate:] select()");
|
||||
perror ("[NSRunLoop acceptInputForMode: beforeDate: ] select()");
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
if (select_return == 0)
|
||||
{
|
||||
NSFreeMapTable (rfd_2_object);
|
||||
NSFreeMapTable (wfd_2_object);
|
||||
NSResetMapTable(_rfdMap);
|
||||
NSResetMapTable(_wfdMap);
|
||||
[NSNotificationQueue runLoopIdle];
|
||||
[self _checkPerformers];
|
||||
_current_mode = saved_mode;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Look at all the file descriptors select() says are ready for reading;
|
||||
notify the corresponding object for each of the ready fd's. */
|
||||
/*
|
||||
* Look at all the file descriptors select() says are ready for reading;
|
||||
* notify the corresponding object for each of the ready fd's.
|
||||
* NB. It is possible for a watcher to be missing from the map - if
|
||||
* the event handler of a previous watcher has 'run' the loop again
|
||||
* before returning.
|
||||
*/
|
||||
for (fd_index = 0; fd_index < FD_SETSIZE; fd_index++)
|
||||
{
|
||||
if (FD_ISSET (fd_index, &write_fds))
|
||||
{
|
||||
id watcher = (id) NSMapGet (wfd_2_object, (void*)fd_index);
|
||||
NSAssert(watcher, NSInternalInconsistencyException);
|
||||
RunLoopWatcher *watcher;
|
||||
|
||||
watcher = NSMapGet(_wfdMap, (void*)fd_index);
|
||||
[watcher eventFor: (void*)(gsaddr)fd_index mode: _current_mode];
|
||||
[NSNotificationQueue runLoopASAP];
|
||||
[NSNotificationQueue runLoopASAP];
|
||||
}
|
||||
if (FD_ISSET (fd_index, &read_fds))
|
||||
{
|
||||
id watcher = (id) NSMapGet (rfd_2_object, (void*)fd_index);
|
||||
NSAssert(watcher, NSInternalInconsistencyException);
|
||||
RunLoopWatcher *watcher;
|
||||
|
||||
watcher = (RunLoopWatcher*)NSMapGet(_rfdMap, (void*)fd_index);
|
||||
[watcher eventFor: (void*)(gsaddr)fd_index mode: _current_mode];
|
||||
[NSNotificationQueue runLoopASAP];
|
||||
[NSNotificationQueue runLoopASAP];
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up before returning. */
|
||||
NSFreeMapTable (rfd_2_object);
|
||||
NSFreeMapTable (wfd_2_object);
|
||||
NSResetMapTable(_rfdMap);
|
||||
NSResetMapTable(_wfdMap);
|
||||
|
||||
[self _checkPerformers];
|
||||
[NSNotificationQueue runLoopASAP];
|
||||
|
@ -1283,7 +1339,7 @@ static int debug_run_loop = 0;
|
|||
|
||||
- (void) run
|
||||
{
|
||||
[self runUntilDate: [NSDate distantFuture]];
|
||||
[self runUntilDate: theFuture];
|
||||
}
|
||||
|
||||
- (void) runUntilDate: date
|
||||
|
@ -1323,11 +1379,11 @@ id NSDefaultRunLoopMode = @"NSDefaultRunLoopMode";
|
|||
RETAIN(argument);
|
||||
for (i = count; i > 0; i--)
|
||||
{
|
||||
item = (RunLoopPerformer*)[_performers objectAtIndex:(i-1)];
|
||||
item = (RunLoopPerformer*)[_performers objectAtIndex: (i-1)];
|
||||
|
||||
if ([item matchesSelector:aSelector target:target argument:argument])
|
||||
if ([item matchesSelector: aSelector target: target argument: argument])
|
||||
{
|
||||
[_performers removeObjectAtIndex:(i-1)];
|
||||
[_performers removeObjectAtIndex: (i-1)];
|
||||
}
|
||||
}
|
||||
RELEASE(argument);
|
||||
|
@ -1356,7 +1412,7 @@ id NSDefaultRunLoopMode = @"NSDefaultRunLoopMode";
|
|||
/* Add new item to list - reverse ordering */
|
||||
if (count == 0)
|
||||
{
|
||||
[_performers addObject:item];
|
||||
[_performers addObject: item];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1364,15 +1420,15 @@ id NSDefaultRunLoopMode = @"NSDefaultRunLoopMode";
|
|||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if ([[_performers objectAtIndex:i] order] <= order)
|
||||
if ([[_performers objectAtIndex: i] order] <= order)
|
||||
{
|
||||
[_performers insertObject:item atIndex:i];
|
||||
[_performers insertObject: item atIndex: i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == count)
|
||||
{
|
||||
[_performers addObject:item];
|
||||
[_performers addObject: item];
|
||||
}
|
||||
}
|
||||
RELEASE(item);
|
||||
|
@ -1381,7 +1437,7 @@ id NSDefaultRunLoopMode = @"NSDefaultRunLoopMode";
|
|||
- (void) removePort: (NSPort*)port
|
||||
forMode: (NSString*)mode
|
||||
{
|
||||
return [self removeEvent:(void*)port type: ET_RPORT forMode:mode all:NO];
|
||||
return [self removeEvent: (void*)port type: ET_RPORT forMode: mode all: NO];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -45,6 +45,39 @@ static o_map_t thread_id_2_nsthread;
|
|||
/* Flag indicating whether the objc runtime ever went multi-threaded. */
|
||||
static BOOL entered_multi_threaded_state;
|
||||
|
||||
inline NSThread*
|
||||
GSCurrentThread()
|
||||
{
|
||||
id t = (id) objc_thread_get_data ();
|
||||
|
||||
/* If an NSThread object for this thread has already been created
|
||||
and stashed away, return it. This depends on the objc runtime
|
||||
initializing objc_thread_get_data() to 0 for newly-created
|
||||
threads. */
|
||||
if (t)
|
||||
return t;
|
||||
|
||||
/* We haven't yet created an NSThread object for this thread; create
|
||||
it. (Doing this here instead of in +detachNewThread.. not only
|
||||
avoids the race condition, it also nicely provides an NSThread on
|
||||
request for the single thread that exists at application
|
||||
start-up, and for thread's created by calling
|
||||
objc_thread_detach() directly.) */
|
||||
t = [[NSThread alloc] init];
|
||||
return t;
|
||||
}
|
||||
|
||||
NSMutableDictionary*
|
||||
GSCurrentThreadDictionary()
|
||||
{
|
||||
NSThread *thread = GSCurrentThread();
|
||||
NSMutableDictionary *dict = thread->_thread_dictionary;
|
||||
|
||||
if (dict == nil)
|
||||
dict = [thread threadDictionary];
|
||||
return dict;
|
||||
}
|
||||
|
||||
void gnustep_base_thread_callback()
|
||||
{
|
||||
/* Post a notification if this is the first new thread to be created.
|
||||
|
@ -115,23 +148,7 @@ void gnustep_base_thread_callback()
|
|||
|
||||
+ (NSThread*) currentThread
|
||||
{
|
||||
id t = (id) objc_thread_get_data ();
|
||||
|
||||
/* If an NSThread object for this thread has already been created
|
||||
and stashed away, return it. This depends on the objc runtime
|
||||
initializing objc_thread_get_data() to 0 for newly-created
|
||||
threads. */
|
||||
if (t)
|
||||
return t;
|
||||
|
||||
/* We haven't yet created an NSThread object for this thread; create
|
||||
it. (Doing this here instead of in +detachNewThread.. not only
|
||||
avoids the race condition, it also nicely provides an NSThread on
|
||||
request for the single thread that exists at application
|
||||
start-up, and for thread's created by calling
|
||||
objc_thread_detach() directly.) */
|
||||
t = [[NSThread alloc] init];
|
||||
return t;
|
||||
return GSCurrentThread();
|
||||
}
|
||||
|
||||
+ (void) detachNewThreadSelector:(SEL)aSelector
|
||||
|
|
Loading…
Reference in a new issue