mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
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:
parent
4fc194d797
commit
97f368c2b8
4 changed files with 132 additions and 46 deletions
|
@ -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>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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!
|
||||
|
|
Loading…
Reference in a new issue