Index: src/OFThread.h ================================================================== --- src/OFThread.h +++ src/OFThread.h @@ -19,10 +19,14 @@ #import "threading.h" @class OFDate; +#ifdef OF_HAVE_BLOCKS +typedef id (^of_thread_block_t)(id object); +#endif + /** * \brief A class for Thread Local Storage keys. */ @interface OFTLSKey: OFObject { @@ -69,20 +73,27 @@ * To use it, you should create a new class derived from it and reimplement * main. */ @interface OFThread: OFObject { +@public id object; of_thread_t thread; -@public enum { OF_THREAD_NOT_RUNNING, OF_THREAD_RUNNING, OF_THREAD_WAITING_FOR_JOIN } running; +#ifdef OF_HAVE_BLOCKS + of_thread_block_t block; +#endif id returnValue; } + +#if defined(OF_HAVE_PROPERTIES) && defined(OF_HAVE_BLOCKS) +@property (retain) of_thread_block_t block; +#endif /** * \return A new, autoreleased thread */ + thread; @@ -90,10 +101,26 @@ /** * \param object An object which is passed for use in the main method or nil * \return A new, autoreleased thread */ + threadWithObject: (id)object; + +#ifdef OF_HAVE_BLOCKS +/** + * \param block A block which is executed by the thread + * \return A new, autoreleased thread + */ ++ threadWithBlock: (of_thread_block_t)block; + +/** + * \param block A block which is executed by the thread + * \param object An object which is passed for use in the main method or nil + * \return A new, autoreleased thread + */ ++ threadWithBlock: (of_thread_block_t)block + object: (id)object; +#endif /** * Sets the Thread Local Storage for the specified key. * * The specified object is first retained and then the object stored before is @@ -163,10 +190,26 @@ /** * \param object An object which is passed for use in the main method or nil * \return An initialized OFThread. */ - initWithObject: (id)object; + +#ifdef OF_HAVE_BLOCKS +/** + * \param block A block which is executed by the thread + * \return An initialized OFThread. + */ +- initWithBlock: (of_thread_block_t)block; + +/** + * \param block A block which is executed by the thread + * \param object An object which is passed for use in the main method or nil + * \return An initialized OFThread. + */ +- initWithBlock: (of_thread_block_t)block + object: (id)object; +#endif /** * The main routine of the thread. You need to reimplement this! * * It can access the object passed to the threadWithObject or initWithObject Index: src/OFThread.m ================================================================== --- src/OFThread.m +++ src/OFThread.m @@ -67,11 +67,18 @@ /* * Nasty workaround for thread implementations which can't return a * value on join. */ +#ifdef OF_HAVE_BLOCKS + if (thread->block != nil) + thread->returnValue = [thread->block(thread->object) retain]; + else + thread->returnValue = [[thread main] retain]; +#else thread->returnValue = [[thread main] retain]; +#endif [thread handleTermination]; thread->running = OF_THREAD_WAITING_FOR_JOIN; @@ -86,10 +93,14 @@ return 0; } @implementation OFThread +#if defined(OF_HAVE_PROPERTIES) && defined(OF_HAVE_BLOCKS) +@synthesize block; +#endif + + (void)initialize { if (self != [OFThread class]) return; @@ -104,10 +115,24 @@ + threadWithObject: (id)object { return [[[self alloc] initWithObject: object] autorelease]; } + +#ifdef OF_HAVE_BLOCKS ++ threadWithBlock: (of_thread_block_t)block +{ + return [[[self alloc] initWithBlock: block] autorelease]; +} + ++ threadWithBlock: (of_thread_block_t)block + object: (id)object +{ + return [[[self alloc] initWithBlock: block + object: object] autorelease]; +} +#endif + (void)setObject: (id)object forTLSKey: (OFTLSKey*)key { id oldObject = of_tlskey_get(key->key); @@ -241,10 +266,34 @@ @throw e; } return self; } + +#ifdef OF_HAVE_BLOCKS +- initWithBlock: (of_thread_block_t)block_ +{ + return [self initWithBlock: block_ + object: nil]; +} + +- initWithBlock: (of_thread_block_t)block_ + object: (id)object_ +{ + self = [super init]; + + @try { + block = [block_ retain]; + object = [object_ retain]; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} +#endif - (id)main { @throw [OFNotImplementedException newWithClass: isa selector: _cmd];