diff --git a/Headers/Foundation/NSThread.h b/Headers/Foundation/NSThread.h index 6f003e2b6..da8c5fedb 100644 --- a/Headers/Foundation/NSThread.h +++ b/Headers/Foundation/NSThread.h @@ -43,6 +43,11 @@ extern "C" { #endif +#if OS_API_VERSION(MAC_OS_X_VERSION_10_12, GS_API_LATEST) +#import +DEFINE_BLOCK_TYPE(GSThreadBlock, void, void); +#endif + /** * This class encapsulates OpenStep threading. See [NSLock] and its * subclasses for handling synchronisation between threads.
@@ -67,6 +72,7 @@ GS_EXPORT_CLASS BOOL _cancelled; BOOL _active; BOOL _finished; + BOOL _targetIsBlock; NSHandler *_exception_handler; // Not retained. NSMutableDictionary *_thread_dictionary; struct autorelease_thread_vars _autorelease_vars; @@ -398,6 +404,29 @@ GS_EXPORT void GSUnregisterCurrentThread (void); #endif +/** + * This category contains convenience + * initialisers and methods for executing + * blocks in different threads and creating + * NSThread objects with a block as entry point. + */ +@interface NSThread (BlockAdditions) + +#if OS_API_VERSION(MAC_OS_X_VERSION_10_12, GS_API_LATEST) +/** + * Detaches a new thread with block as its entry point. + */ ++ (void)detachNewThreadWithBlock: (GSThreadBlock)block; + +/** + * Initialises a NSThread object with block as the + * entry point. + */ +- (instancetype)initWithBlock: (GSThreadBlock)block; +#endif // OS_API_VERSION + +@end + /* * Notification Strings. * NSBecomingMultiThreaded and NSThreadExiting are defined for strict diff --git a/Source/NSThread.m b/Source/NSThread.m index f3ec8d720..af7067f71 100644 --- a/Source/NSThread.m +++ b/Source/NSThread.m @@ -30,6 +30,7 @@ NSThread class reference */ +#include "GNUstepBase/GSBlocks.h" #import "common.h" #import "GSPThread.h" @@ -1337,7 +1338,15 @@ - (void) main NSStringFromSelector(_cmd)]; } - [_target performSelector: _selector withObject: _arg]; + if (_targetIsBlock) + { + GSThreadBlock block = (GSThreadBlock)_target; + CALL_BLOCK_NO_ARGS(block); + } + else + { + [_target performSelector: _selector withObject: _arg]; + } } - (NSString*) name @@ -2414,6 +2423,31 @@ - (void) performSelectorInBackground: (SEL)aSelector @end +@implementation NSThread (BlockAdditions) + ++ (void)detachNewThreadWithBlock: (GSThreadBlock)block +{ + NSThread *thread; + + thread = [[NSThread alloc] initWithBlock: block]; + [thread start]; + + RELEASE(thread); +} + +- (instancetype)initWithBlock: (GSThreadBlock)block +{ + if (nil != (self = [self init])) + { + _targetIsBlock = YES; + /* Copy block to heap */ + _target = _Block_copy(block); + } + return self; +} + +@end + /** *

* This function is provided to let threads started by some other