- NSLock tryLock, lockBeforeDate: implementation for Windows

- that means @synchronized now works
- performSelector:onThread: and friends
- NSFastEnumeration is now located in NSEnumerator.h
This commit is contained in:
Johannes Fortmann 2008-04-06 17:03:54 +00:00
parent 522e29b18b
commit 89d714df1b
9 changed files with 105 additions and 41 deletions

View File

@ -8445,7 +8445,6 @@
EXECUTABLE_SUFFIX = .1.0.dll;
GCC_ENABLE_CPP_EXCEPTIONS = NO;
GCC_ENABLE_CPP_RTTI = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = NO;

View File

@ -8,20 +8,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
#import <Foundation/NSObject.h>
#import <Foundation/NSRange.h>
#import <Foundation/NSEnumerator.h>
@class NSString,NSEnumerator,NSDictionary,NSPredicate,NSIndexSet,NSURL;
typedef struct
{
unsigned long state;
id *itemsPtr;
unsigned long *mutationsPtr;
unsigned long extra[5];
} NSFastEnumerationState;
@protocol NSFastEnumeration
-(NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)length;
@end
@class NSString,NSDictionary,NSPredicate,NSIndexSet,NSURL;
@interface NSArray : NSObject <NSCopying,NSMutableCopying,NSCoding,NSFastEnumeration>

View File

@ -10,7 +10,19 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
@class NSArray;
@interface NSEnumerator:NSObject
typedef struct
{
unsigned long state;
id *itemsPtr;
unsigned long *mutationsPtr;
unsigned long extra[5];
} NSFastEnumerationState;
@protocol NSFastEnumeration
-(NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)length;
@end
@interface NSEnumerator:NSObject <NSFastEnumeration>
-nextObject;
-(NSArray *)allObjects;

View File

@ -26,15 +26,6 @@ void _NSInitializeSynchronizedDirective()
synchronizationLocks=[NSMutableDictionary new];
syncLocksLock=[NSLock new];
}
if(![syncLocksLock respondsToSelector:@selector(tryLock)])
{
NSLog(@"%@ doesn't respond to tryLock in _NSInitializeSynchronizedDirective. Synchronization will be disabled.", syncLocksLock);
[synchronizationLocks release];
synchronizationLocks=nil;
[syncLocksLock release];
syncLocksLock=nil;
}
}
enum {
@ -52,7 +43,6 @@ FOUNDATION_EXPORT int objc_sync_enter(id obj)
return OBJC_SYNC_NOT_INITIALIZED;
id key=[[NSValue alloc] initWithBytes:&obj objCType:@encode(id)];
[syncLocksLock lock];
id lock=[synchronizationLocks objectForKey:key];

View File

@ -21,4 +21,7 @@ void NSThreadSetUncaughtExceptionHandler(NSUncaughtExceptionHandler *function);
-sharedObjectForClassName:(NSString *)className;
-(void)setExecuting:(BOOL)executing;
-(void)setFinished:(BOOL)finished;
@end

View File

@ -25,6 +25,9 @@ FOUNDATION_EXPORT NSString *NSThreadWillExitNotification;
SEL _selector;
id _argument;
id _target;
BOOL _cancelled;
BOOL _executing;
BOOL _finished;
}
+(BOOL)isMultiThreaded;

View File

@ -14,6 +14,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
#import <Foundation/NSRaise.h>
#import <Foundation/NSPlatform.h>
#import <Foundation/NSNotificationCenter.h>
#import <Foundation/NSRunLoop.h>
#import "NSThread-Private.h"
NSString *NSDidBecomeSingleThreadedNotification=@"NSDidBecomeSingleThreadedNotification";
NSString *NSWillBecomeMultiThreadedNotification=@"NSWillBecomeMultiThreadedNotification";
@ -59,10 +61,13 @@ static id mainThread = nil;
[_target performSelector: _selector withObject: _argument];
}
static unsigned nsThreadStartThread(void* thread)
static unsigned nsThreadStartThread(NSThread* thread)
{
NSPlatformSetCurrentThread(thread);
[thread setExecuting:YES];
[(NSThread*)thread main];
[thread setExecuting:NO];
[thread setFinished:YES];
NSPlatformSetCurrentThread(nil);
[(NSThread*)thread release];
return 0;
@ -145,28 +150,35 @@ static unsigned nsThreadStartThread(void* thread)
}
-(BOOL)isCancelled {
NSUnimplementedMethod();
return 0;
return _cancelled;
}
-(BOOL)isExecuting {
NSUnimplementedMethod();
return 0;
return _executing;
}
-(BOOL)isFinished {
NSUnimplementedMethod();
return 0;
return _finished;
}
-(void)cancel {
NSUnimplementedMethod();
_cancelled=YES;
}
-(NSString *)name {
return _name;
}
-(void)setExecuting:(BOOL)executing
{
_executing=executing;
}
-(void)setFinished:(BOOL)finished
{
_finished=finished;
}
-(NSUInteger)stackSize {
NSUnimplementedMethod();
return 0;
@ -251,17 +263,62 @@ void NSThreadSetUncaughtExceptionHandler(NSUncaughtExceptionHandler *function) {
@end
@implementation NSObject(NSThread)
-(void)_performSelectorOnMainThreadHelper:(NSArray*)selectorAndArguments {
NSLock* waitingLock=[selectorAndArguments objectAtIndex:0];
SEL selector=NSSelectorFromString([selectorAndArguments objectAtIndex:1]);
id object=[[selectorAndArguments objectAtIndex:2] pointerValue];
[self performSelector:selector withObject:object];
[waitingLock unlock];
}
- (void)performSelector:(SEL)selector onThread:(NSThread *)thread withObject:(id)object waitUntilDone:(BOOL)waitUntilDone modes:(NSArray *)modes
{
id runloop=_NSThreadSharedInstance(thread, @"NSRunLoop", NO);
if(waitUntilDone)
{
if(thread==[NSThread currentThread])
{
[self performSelector:selector withObject:object];
}
else
{
if(!runloop)
[NSException raise:NSInvalidArgumentException format:@"thread %@ has no runloop in %@", thread, NSStringFromSelector(_cmd)];
NSLock *waitingLock=[NSLock new];
[waitingLock lock];
[runloop performSelector:@selector(_performSelectorOnMainThreadHelper:)
target:self
argument:[NSArray arrayWithObjects:waitingLock, NSStringFromSelector(selector), [NSValue valueWithPointer:object], nil]
order:0
modes:modes];
[waitingLock lock];
[waitingLock unlock];
[waitingLock release];
}
}
else
{
if(!runloop)
[NSException raise:NSInvalidArgumentException format:@"thread %@ has no runloop in %@", thread, NSStringFromSelector(_cmd)];
[runloop performSelector:selector target:self argument:object order:0 modes:modes];
}
}
-(void)performSelectorOnMainThread:(SEL)selector withObject:(id)object waitUntilDone:(BOOL)waitUntilDone modes:(NSArray *)modes {
NSUnimplementedMethod();
[self performSelector:selector onThread:[NSThread mainThread] withObject:object waitUntilDone:waitUntilDone modes:modes];
}
-(void)performSelectorOnMainThread:(SEL)selector withObject:(id)object waitUntilDone:(BOOL)waitUntilDone {
NSUnimplementedMethod();
// TODO: should be NSRunLoopCommonModes here
[self performSelectorOnMainThread:selector withObject:object waitUntilDone:waitUntilDone modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]];
}
-(void)performSelectorInBackground:(SEL)selector withObject:object {
NSUnimplementedMethod();
[NSThread detachNewThreadSelector:selector toTarget:self withObject:object];
}
@end

View File

@ -10,7 +10,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
#import <windows.h>
@interface NSLock_win32 : NSObject {
CRITICAL_SECTION _lock;
HANDLE _lock;
}
@end

View File

@ -8,25 +8,36 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
// Original - Christopher Lloyd <cjwl@objc.net>
#import <Foundation/NSLock_win32.h>
#import <Foundation/NSDate.h>
@implementation NSLock_win32
-init {
InitializeCriticalSection(&_lock);
_lock=CreateSemaphore(NULL, 1, 1, NULL);
return self;
}
-(void)dealloc {
DeleteCriticalSection(&_lock);
CloseHandle(_lock);
[super dealloc];
}
-(void)lock {
EnterCriticalSection(&_lock);
WaitForSingleObject(_lock, INFINITE);
}
-(void)unlock {
LeaveCriticalSection(&_lock);
ReleaseSemaphore(_lock, 1, NULL);
}
-(BOOL)lockBeforeDate:(NSDate*)date
{
DWORD timeout=[date timeIntervalSinceNow]*1000.0;
return (WaitForSingleObject(_lock, timeout)==0);
}
-(BOOL)tryLock
{
return (WaitForSingleObject(_lock, 0)==0);
}
@end