Add thread priority and checking for selectors.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@14356 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-Macdonald 2002-08-27 17:02:05 +00:00
parent 4fc194d797
commit 97f368c2b8
4 changed files with 132 additions and 46 deletions

View file

@ -3,6 +3,8 @@
* Source/Additions/GSXML.m: Integrated GSXPath code by Nicola Pero
provides an API to use the xpath support built into libxml from
version 2.3 onwards.
* Source/NSThread.m: Implement new priority methods.
* Source/NSObject.m: Raise exception when passed null selector.
2002-08-27 Richard Frith-Macdonald <rfm@gnu.org>

View file

@ -33,13 +33,6 @@
#include <Foundation/NSException.h>
#include <Foundation/NSAutoreleasePool.h> // for struct autorelease_thread_vars
typedef enum
{
NSInteractiveThreadPriority,
NSBackgroundThreadPriority,
NSLowThreadPriority
} NSThreadPriority;
@interface NSThread : NSObject
{
id _target;
@ -57,12 +50,13 @@ typedef enum
+ (void) detachNewThreadSelector: (SEL)aSelector
toTarget: (id)aTarget
withObject: (id)anArgument;
+ (BOOL) isMultiThreaded;
- (NSMutableDictionary*) threadDictionary;
+ (void) sleepUntilDate: (NSDate*)date;
+ (void) exit;
+ (BOOL) isMultiThreaded;
+ (void) setThreadPriority: (double)pri;
+ (void) sleepUntilDate: (NSDate*)date;
+ (double) threadPriority;
- (NSMutableDictionary*) threadDictionary;
@end

View file

@ -1119,9 +1119,13 @@ static BOOL double_release_check_enabled = NO;
* where a subclass implements -forwardInvocation: to respond to
* selectors not normally handled ... in these cases the subclass
* may override this method to handle it.
* <br />Raises NSInvalidArgumentException if given a null selector.
*/
+ (BOOL) instancesRespondToSelector: (SEL)aSelector
{
if (aSelector == 0)
[NSException raise: NSInvalidArgumentException
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
#if 0
return (class_get_instance_method(self, aSelector) != METHOD_NULL);
#else
@ -1170,8 +1174,17 @@ static BOOL double_release_check_enabled = NO;
return [[self class] conformsToProtocol: aProtocol];
}
/**
* Returns a pointer to the C function implementing the method used
* to respond to messages with aSelector by instances of the receiving
* class.
* <br />Raises NSInvalidArgumentException if given a null selector.
*/
+ (IMP) instanceMethodForSelector: (SEL)aSelector
{
if (aSelector == 0)
[NSException raise: NSInvalidArgumentException
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
/*
* Since 'self' is an class, get_imp() will get the instance method.
*/
@ -1181,9 +1194,13 @@ static BOOL double_release_check_enabled = NO;
/**
* Returns a pointer to the C function implementing the method used
* to respond to messages with aSelector.
* <br />Raises NSInvalidArgumentException if given a null selector.
*/
- (IMP) methodForSelector: (SEL)aSelector
{
if (aSelector == 0)
[NSException raise: NSInvalidArgumentException
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
/*
* If 'self' is an instance, GSObjCClass() will get the class,
* and get_imp() will get the instance method.
@ -1197,10 +1214,17 @@ static BOOL double_release_check_enabled = NO;
* Returns a pointer to the C function implementing the method used
* to respond to messages with aSelector whihc are sent to instances
* of the receiving class.
* <br />Raises NSInvalidArgumentException if given a null selector.
*/
+ (NSMethodSignature*) instanceMethodSignatureForSelector: (SEL)aSelector
{
struct objc_method* mth = class_get_instance_method(self, aSelector);
struct objc_method *mth;
if (aSelector == 0)
[NSException raise: NSInvalidArgumentException
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
mth = class_get_instance_method(self, aSelector);
return mth ? [NSMethodSignature signatureWithObjCTypes:mth->method_types]
: nil;
}
@ -1208,6 +1232,7 @@ static BOOL double_release_check_enabled = NO;
/**
* Returns the method signature describing how the receiver would handle
* a message with aSelector.
* <br />Raises NSInvalidArgumentException if given a null selector.
*/
- (NSMethodSignature*) methodSignatureForSelector: (SEL)aSelector
{
@ -1215,9 +1240,9 @@ static BOOL double_release_check_enabled = NO;
struct objc_method *mth;
if (aSelector == 0)
{
return nil;
}
[NSException raise: NSInvalidArgumentException
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
mth = (GSObjCIsInstance(self)
? class_get_instance_method(GSObjCClass(self), aSelector)
: class_get_class_method(GSObjCClass(self), aSelector));
@ -1282,13 +1307,17 @@ static BOOL double_release_check_enabled = NO;
format: @"%s(%s) does not recognize %s",
object_get_class_name(self),
GSObjCIsInstance(self) ? "instance" : "class",
sel_get_name(aSelector)];
aSelector ? sel_get_name(aSelector) : "(null)"];
}
- (retval_t) forward: (SEL)aSel : (arglist_t)argFrame
{
NSInvocation *inv;
if (aSel == 0)
[NSException raise: NSInvalidArgumentException
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
inv = AUTORELEASE([[NSInvocation alloc] initWithArgframe: argFrame
selector: aSel]);
[self forwardInvocation: inv];
@ -1506,17 +1535,15 @@ static BOOL double_release_check_enabled = NO;
* Causes the receiver to execute the method implementation corresponding
* to aSelector and returns the result.<br />
* The method must be one which takes no arguments and returns an object.
* <br />Raises NSInvalidArgumentException if given a null selector.
*/
- (id) performSelector: (SEL)aSelector
{
IMP msg;
if (aSelector == 0)
{
[NSException raise: NSInvalidArgumentException
format: @"null selector passed to %s", sel_get_name(_cmd)];
return nil;
}
[NSException raise: NSInvalidArgumentException
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
msg = get_imp(GSObjCClass(self), aSelector);
if (!msg)
@ -1532,17 +1559,15 @@ static BOOL double_release_check_enabled = NO;
* Causes the receiver to execute the method implementation corresponding
* to aSelector and returns the result.<br />
* The method must be one which takes one argument and returns an object.
* <br />Raises NSInvalidArgumentException if given a null selector.
*/
- (id) performSelector: (SEL)aSelector withObject: (id) anObject
{
IMP msg;
if (aSelector == 0)
{
[NSException raise: NSInvalidArgumentException
format: @"null selector passed to %s", sel_get_name(_cmd)];
return nil;
}
[NSException raise: NSInvalidArgumentException
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
msg = get_imp(GSObjCClass(self), aSelector);
if (!msg)
@ -1559,6 +1584,7 @@ static BOOL double_release_check_enabled = NO;
* Causes the receiver to execute the method implementation corresponding
* to aSelector and returns the result.<br />
* The method must be one which takes two arguments and returns an object.
* <br />Raises NSInvalidArgumentException if given a null selector.
*/
- (id) performSelector: (SEL)aSelector
withObject: (id) object1
@ -1567,11 +1593,8 @@ static BOOL double_release_check_enabled = NO;
IMP msg;
if (aSelector == 0)
{
[NSException raise: NSInvalidArgumentException
format: @"null selector passed to %s", sel_get_name(_cmd)];
return nil;
}
[NSException raise: NSInvalidArgumentException
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
msg = get_imp(GSObjCClass(self), aSelector);
if (!msg)
@ -1631,13 +1654,14 @@ static BOOL double_release_check_enabled = NO;
* where a subclass implements -forwardInvocation: to respond to
* selectors not normally handled ... in these cases the subclass
* may override this method to handle it.
* <br />Raises NSInvalidArgumentException if given a null selector.
*/
- (BOOL) respondsToSelector: (SEL)aSelector
{
if (aSelector == 0)
{
return NO;
}
[NSException raise: NSInvalidArgumentException
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
return __objc_responds_to(self, aSelector);
}
@ -1812,6 +1836,10 @@ static BOOL double_release_check_enabled = NO;
- (retval_t) performv: (SEL)aSel :(arglist_t)argFrame
{
if (aSel == 0)
[NSException raise: NSInvalidArgumentException
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
return objc_msg_sendv(self, aSel, argFrame);
}
@ -1822,8 +1850,13 @@ static BOOL double_release_check_enabled = NO;
+ (NSMethodSignature*) instanceMethodSignatureForSelector: (SEL)aSelector
{
struct objc_method* mth = class_get_instance_method(self, aSelector);
struct objc_method* mth;
if (aSelector == 0)
[NSException raise: NSInvalidArgumentException
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
mth = class_get_instance_method(self, aSelector);
return mth ? [NSMethodSignature signatureWithObjCTypes:mth->method_types]
: nil;
}
@ -1843,7 +1876,8 @@ static BOOL double_release_check_enabled = NO;
{
[NSException
raise: NSGenericException
format: @"method %s not implemented in %s(%s)", sel_get_name(aSel),
format: @"method %s not implemented in %s(%s)",
aSel ? sel_get_name(aSel) : "(null)",
object_get_class_name(self),
GSObjCIsInstance(self) ? "instance" : "class"];
return nil;
@ -1855,7 +1889,7 @@ static BOOL double_release_check_enabled = NO;
format: @"%s(%s) does not recognize %s",
object_get_class_name(self),
GSObjCIsInstance(self) ? "instance" : "class",
sel_get_name(aSel)];
aSel ? sel_get_name(aSel) : "(null)"];
return nil;
}
@ -2034,12 +2068,20 @@ static BOOL double_release_check_enabled = NO;
+ (struct objc_method_description *) descriptionForInstanceMethod: (SEL)aSel
{
if (aSel == 0)
[NSException raise: NSInvalidArgumentException
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
return ((struct objc_method_description *)
class_get_instance_method(self, aSel));
}
- (struct objc_method_description *) descriptionForMethod: (SEL)aSel
{
if (aSel == 0)
[NSException raise: NSInvalidArgumentException
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
return ((struct objc_method_description *)
(GSObjCIsInstance(self)
?class_get_instance_method(GSObjCClass(self), aSel)
@ -2066,7 +2108,7 @@ static BOOL double_release_check_enabled = NO;
format: @"subclass %s(%s) should override %s",
object_get_class_name(self),
GSObjCIsInstance(self) ? "instance" : "class",
sel_get_name(aSel)];
aSel ? sel_get_name(aSel) : "(null)"];
return nil;
}
@ -2077,7 +2119,7 @@ static BOOL double_release_check_enabled = NO;
format: @"%s(%s) should not implement %s",
object_get_class_name(self),
GSObjCIsInstance(self) ? "instance" : "class",
sel_get_name(aSel)];
aSel ? sel_get_name(aSel) : "(null)"];
return nil;
}
@ -2213,6 +2255,10 @@ _fastMallocBuffer(unsigned size)
@implementation NSZombie
- (retval_t) forward:(SEL)aSel :(arglist_t)argFrame
{
if (aSel == 0)
[NSException raise: NSInvalidArgumentException
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
GSLogZombie(self, aSel);
return 0;
}

View file

@ -224,7 +224,7 @@ gnustep_base_thread_callback()
return t;
}
/*
/**
* Create a new thread - use this method rather than alloc-init
*/
+ (void) detachNewThreadSelector: (SEL)aSelector
@ -256,7 +256,7 @@ gnustep_base_thread_callback()
}
}
/*
/**
* Terminating a thread
* What happens if the thread doesn't call +exit - it doesn't terminate!
*/
@ -326,13 +326,39 @@ gnustep_base_thread_callback()
}
}
/**
* Returns a flag to say whether the application is multi-threaded or not.
* An application is considered to be multi-threaded if any thread other
* than the main thread has been started, irrespective of whether that
* thread has since terminated.
*/
+ (BOOL) isMultiThreaded
{
return entered_multi_threaded_state;
}
/*
* Delaying a thread
/**
* Set the priority of the current thread. This is a value in the
* range 0.0 (lowest) to 1.0 (highest) which is mapped to the underlying
* system priorities. The current gnu objc runtime supports three
* priority levels which you can obtain using values of 0.0, 0.5, and 1.0
*/
+ (void) setThreadPriority: (double)pri
{
int p;
if (pri <= 0.3)
p = OBJC_THREAD_LOW_PRIORITY;
else if (pri <= 0.6)
p = OBJC_THREAD_BACKGROUND_PRIORITY;
else
p = OBJC_THREAD_INTERACTIVE_PRIORITY;
objc_thread_set_priority(p);
}
/**
* Delaying a thread ... pause until the specified date.
*/
+ (void) sleepUntilDate: (NSDate*)date
{
@ -374,6 +400,23 @@ gnustep_base_thread_callback()
}
}
/**
* Return the priority of the current thread.
*/
+ (double) threadPriority
{
int p = objc_thread_get_priority();
if (p == OBJC_THREAD_LOW_PRIORITY)
return 0.0;
else if (p == OBJC_THREAD_BACKGROUND_PRIORITY)
return 0.5;
else if (p == OBJC_THREAD_INTERACTIVE_PRIORITY)
return 1.0;
else
return 0.0; // Unknown.
}
/*
@ -456,8 +499,9 @@ gnustep_base_thread_callback()
[NSThread exit];
}
/*
* Thread dictionary
/**
* Return the thread dictionary. This dictionary can be used to store
* arbitrary thread specific data.<br />
* NB. This cannot be autoreleased, since we cannot be sure that the
* autorelease pool for the thread will continue to exist for the entire
* life of the thread!