Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -46,10 +46,11 @@ OFString+Serialization.m \ OFString+URLEncoding.m \ OFString+XMLEscaping.m \ OFString+XMLUnescaping.m \ OFSystemInfo.m \ + OFThread.m \ OFTimer.m \ OFURL.m \ OFXMLAttribute.m \ OFXMLCDATA.m \ OFXMLCharacters.m \ @@ -76,11 +77,10 @@ OFStreamSocket.m \ OFTCPSocket.m SRCS_THREADS = OFCondition.m \ OFMutex.m \ OFRecursiveMutex.m \ - OFThread.m \ OFThreadPool.m \ OFTLSKey.m INCLUDES_THREADS = threading.h INCLUDES := ${SRCS:.m=.h} \ Index: src/OFRunLoop.m ================================================================== --- src/OFRunLoop.m +++ src/OFRunLoop.m @@ -21,12 +21,12 @@ #import "OFRunLoop.h" #import "OFDictionary.h" #ifdef OF_HAVE_SOCKETS # import "OFStreamObserver.h" #endif +#import "OFThread.h" #ifdef OF_HAVE_THREADS -# import "OFThread.h" # import "OFMutex.h" #endif #import "OFSortedList.h" #import "OFTimer.h" #import "OFDate.h" Index: src/OFThread.h ================================================================== --- src/OFThread.h +++ src/OFThread.h @@ -13,13 +13,15 @@ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" -#import "OFTLSKey.h" +#ifdef OF_HAVE_THREADS +# import "OFTLSKey.h" -#import "threading.h" +# import "threading.h" +#endif /* Haiku used to define this for some unknown reason which causes trouble */ #ifdef protected # undef protected #endif @@ -28,11 +30,11 @@ @class OFDate; @class OFSortedList; @class OFRunLoop; -#ifdef OF_HAVE_BLOCKS +#if defined(OF_HAVE_THREADS) && defined(OF_HAVE_BLOCKS) /*! * @brief A block to be executed in a new thread. * * @return The object which should be returned when the thread is joined */ @@ -48,54 +50,56 @@ * @warning Even though the OFCopying protocol is implemented, it does *not* * return an independent copy of the thread, but instead retains it. * This is so that the thread can be used as a key for a dictionary, * so context can be associated with a thread. */ -@interface OFThread: OFObject +@interface OFThread: OFObject +#ifdef OF_HAVE_THREADS + { -#ifdef OF_THREAD_M +# ifdef OF_THREAD_M @public -#else +# else @private -#endif +# endif of_thread_t _thread; enum { OF_THREAD_NOT_RUNNING, OF_THREAD_RUNNING, OF_THREAD_WAITING_FOR_JOIN } _running; -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS of_thread_block_t _block; -#endif +# endif id _returnValue; OFRunLoop *_runLoop; OFString *_name; } -#ifdef OF_HAVE_PROPERTIES -# ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_PROPERTIES +# ifdef OF_HAVE_BLOCKS @property (copy) of_thread_block_t block; -# endif +# endif @property (copy) OFString *name; -#endif +# endif /*! * @brief Creates a new thread. * * @return A new, autoreleased thread */ + (instancetype)thread; -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS /*! * @brief Creates a new thread with the specified block. * * @param block A block which is executed by the thread * @return A new, autoreleased thread */ + (instancetype)threadWithBlock: (of_thread_block_t)block; -#endif +# endif /*! * @brief Sets the Thread Local Storage for the specified key. * * The specified object is first retained and then the object stored before is @@ -129,10 +133,11 @@ * @brief Returns the main thread. * * @return The main thread */ + (OFThread*)mainThread; +#endif /*! * @brief Suspends execution of the current thread for the specified time * interval. * @@ -146,15 +151,16 @@ * @param date The date to wait for */ + (void)sleepUntilDate: (OFDate*)date; /*! - * @brief Yields a processor voluntarily and moves the thread at the end of the + * @brief Yields a processor voluntarily and moves the thread to the end of the * queue for its priority. */ + (void)yield; +#ifdef OF_HAVE_THREADS /*! * @brief Terminates the current thread, letting it return nil. */ + (void)terminate; @@ -165,19 +171,19 @@ */ + (void)terminateWithObject: (id)object; + (void)OF_createMainThread; -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS /*! * @brief Initializes an already allocated thread with the specified block. * * @param block A block which is executed by the thread * @return An initialized OFThread. */ - initWithBlock: (of_thread_block_t)block; -#endif +# endif /*! * @brief The main routine of the thread. You need to reimplement this! * * It can access the object passed to the threadWithObject or initWithObject @@ -225,6 +231,7 @@ * @brief Sets the name for the thread. * * @param name The name for the thread */ - (void)setName: (OFString*)name; +#endif @end Index: src/OFThread.m ================================================================== --- src/OFThread.m +++ src/OFThread.m @@ -18,18 +18,22 @@ #define OF_THREAD_M #define __NO_EXT_QNX +#include #include #ifndef _WIN32 # include +#endif + +#ifdef OF_HAVE_SCHED_YIELD # include #endif -#ifdef __HAIKU__ +#if defined(OF_HAVE_THREADS) && defined(__HAIKU__) # include #endif #import "OFRunLoop.h" #import "OFThread.h" @@ -42,20 +46,25 @@ # include #endif #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" +#import "OFNotImplementedException.h" #import "OFOutOfRangeException.h" -#import "OFThreadJoinFailedException.h" -#import "OFThreadStartFailedException.h" -#import "OFThreadStillRunningException.h" +#ifdef OF_HAVE_THREADS +# import "OFThreadJoinFailedException.h" +# import "OFThreadStartFailedException.h" +# import "OFThreadStillRunningException.h" +#endif #ifdef OF_HAVE_ATOMIC_OPS # import "atomic.h" #endif #import "autorelease.h" -#import "threading.h" + +#ifdef OF_HAVE_THREADS +# import "threading.h" static of_tlskey_t threadSelfKey; static OFThread *mainThread; static id @@ -71,54 +80,56 @@ /* * Nasty workaround for thread implementations which can't return a * value on join. */ -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS if (thread->_block != NULL) thread->_returnValue = [thread->_block() retain]; else -#endif +# endif thread->_returnValue = [[thread main] retain]; [thread handleTermination]; thread->_running = OF_THREAD_WAITING_FOR_JOIN; [OFTLSKey OF_callAllDestructors]; -#ifdef OF_OBJFW_RUNTIME +# ifdef OF_OBJFW_RUNTIME /* * As the values returned by objc_autoreleasePoolPush() in the ObjFW * runtime are not actually pointers, but sequential numbers, 0 means * we pop everything. */ objc_autoreleasePoolPop(0); -#endif +# endif [thread release]; return 0; } static void set_thread_name(OFThread *thread) { -#ifdef __HAIKU__ +# ifdef __HAIKU__ OFString *name = thread->_name; if (name == nil) name = [thread className]; rename_thread(get_pthread_thread_id(thread->_thread), [name UTF8String]); -#endif +# endif } +#endif @implementation OFThread -#if defined(OF_HAVE_PROPERTIES) && defined(OF_HAVE_BLOCKS) +#ifdef OF_HAVE_THREADS +# if defined(OF_HAVE_PROPERTIES) && defined(OF_HAVE_BLOCKS) @synthesize block = _block; -#endif +# endif + (void)initialize { if (self != [OFThread class]) return; @@ -131,16 +142,16 @@ + (instancetype)thread { return [[[self alloc] init] autorelease]; } -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS + (instancetype)threadWithBlock: (of_thread_block_t)block { return [[[self alloc] initWithBlock: block] autorelease]; } -#endif +# endif + (void)setObject: (id)object forTLSKey: (OFTLSKey*)key { id oldObject = of_tlskey_get(key->_key); @@ -164,10 +175,11 @@ + (OFThread*)mainThread { return mainThread; } +#endif + (void)sleepForTimeInterval: (double)seconds { if (seconds < 0) @throw [OFOutOfRangeException exceptionWithClass: self]; @@ -211,10 +223,11 @@ #else [self sleepForTimeInterval: 0]; #endif } +#ifdef OF_HAVE_THREADS + (void)terminate { [self terminateWithObject: nil]; } @@ -229,18 +242,18 @@ thread->_running = OF_THREAD_WAITING_FOR_JOIN; } [OFTLSKey OF_callAllDestructors]; -#ifdef OF_OBJFW_RUNTIME +# ifdef OF_OBJFW_RUNTIME /* * As the values returned by objc_autoreleasePoolPush() in the ObjFW * runtime are not actually pointers, but sequential numbers, 0 means * we pop everything. */ objc_autoreleasePoolPop(0); -#endif +# endif [thread release]; of_thread_exit(); } @@ -253,11 +266,11 @@ if (!of_tlskey_set(threadSelfKey, mainThread)) @throw [OFInitializationFailedException exceptionWithClass: self]; } -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS - initWithBlock: (of_thread_block_t)block { self = [super init]; @try { @@ -267,11 +280,11 @@ @throw e; } return self; } -#endif +# endif - (id)main { [[OFRunLoop currentRunLoop] run]; @@ -328,23 +341,23 @@ return [self retain]; } - (OFRunLoop*)runLoop { -#ifdef OF_HAVE_ATOMIC_OPS +# ifdef OF_HAVE_ATOMIC_OPS if (_runLoop == nil) { OFRunLoop *tmp = [[OFRunLoop alloc] init]; if (!of_atomic_cmpswap_ptr((void**)&_runLoop, nil, tmp)) [tmp release]; } -#else +# else @synchronized (self) { if (_runLoop == nil) _runLoop = [[OFRunLoop alloc] init]; } -#endif +# endif return [[_runLoop retain] autorelease]; } - (OFString*)name @@ -377,6 +390,19 @@ [_returnValue release]; [_runLoop release]; [super dealloc]; } +#else +- init +{ + @try { + [self doesNotRecognizeSelector: _cmd]; + } @catch (id e) { + [self release]; + @throw e; + } + + abort(); +} +#endif @end Index: src/ObjFW.h ================================================================== --- src/ObjFW.h +++ src/ObjFW.h @@ -160,13 +160,13 @@ #ifdef OF_HAVE_ATOMIC_OPS # import "atomic.h" #endif #import "OFLocking.h" +#import "OFThread.h" #ifdef OF_HAVE_THREADS # import "threading.h" -# import "OFThread.h" # import "OFThreadPool.h" # import "OFTLSKey.h" # import "OFMutex.h" # import "OFRecursiveMutex.h" # import "OFCondition.h"