add thread safety test for initialize methods in different classes calling each other

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@34460 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2012-01-08 15:57:43 +00:00
parent 3970d58fdc
commit 3fd1294c53

View file

@ -1,3 +1,4 @@
#import <Foundation/NSDictionary.h>
#import <Foundation/NSThread.h>
#import <Foundation/NSLock.h>
#include <unistd.h>
@ -20,6 +21,12 @@
+ (void) doNothing;
@end
@interface Mutual1 : NSObject
@end
@interface Mutual2 : NSObject
@end
static NSCondition *l;
static volatile int init0, init1, init2, init3;
static int initCount = 0;
@ -105,6 +112,43 @@ static volatile int finished = 2;
}
@end
static int mutual = 0;
@implementation Mutual1
+ (void) initialize
{
[NSThread sleepForTimeInterval: 0.5];
[Mutual2 class];
mutual++;
}
@end
@implementation Mutual2
+ (void) initialize
{
[NSThread sleepForTimeInterval: 0.5];
[Mutual1 class];
mutual++;
}
@end
@interface NSObject (Mutual)
+ (void) mutual1: (id)ignored;
+ (void) mutual2: (id)ignored;
@end
@implementation NSObject (Mutual)
+ (void) mutual1: (id)ignored
{
[Mutual1 class];
}
+ (void) mutual2: (id)ignored
{
[Mutual2 class];
}
@end
static void
alarmed(int sig)
{
@ -117,12 +161,14 @@ alarmed(int sig)
/**
* Test the behaviour of +initialize.
* It's an undocumented (but nivce) feature that the Apple runtime lets
* It's an undocumented (but nice) feature that the Apple runtime lets
* both of the +initialize methods run concurrently, however the first
* one will block implicitly until the second one has completed.
*/
int main(void)
{
NSDate *when;
[NSAutoreleasePool new];
START_SET("+initialize")
@ -132,6 +178,22 @@ int main(void)
*/
PASS(1, "initialize test starts");
/* Make sure that classes whose +initialise methods call each other
* can operate safely.
*/
[NSThread detachNewThreadSelector: @selector(mutual1:)
toTarget: [NSObject class]
withObject: nil];
[NSThread detachNewThreadSelector: @selector(mutual2:)
toTarget: [NSObject class]
withObject: nil];
when = [NSDate dateWithTimeIntervalSinceNow: 10.0];
while (mutual < 2 && [when timeIntervalSinceNow] > 0.0)
{
[NSThread sleepForTimeInterval: 0.1];
}
PASS(2 == mutual, "mutually dependent +initialize is thread-safe");
/* Make sure that when a class without its own +initialise is first used,
* the inherited +initialize is called instead.
*/