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:
Richard Frith-MacDonald 1999-04-19 14:29:52 +00:00
parent 832c4c2ec2
commit 84e7ffcdef
17 changed files with 697 additions and 319 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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 */

View file

@ -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)
{

View file

@ -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++;

View file

@ -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

View file

@ -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) {
/*

View file

@ -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

View file

@ -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)
{

View file

@ -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;
}

View file

@ -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)

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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