Index: Doxyfile ================================================================== --- Doxyfile +++ Doxyfile @@ -6,14 +6,15 @@ GENERATE_LATEX = NO HIDE_UNDOC_CLASSES = YES HIDE_UNDOC_MEMBERS = YES PREDEFINED = OF_HAVE_PROPERTIES \ OF_HAVE_BLOCKS \ + OF_THREADS \ OF_SENTINEL \ OF_RETURNS_RETAINED \ OF_RETURNS_NOT_RETAINED \ OF_RETURNS_INNER_POINTER \ OF_CONSUMED \ OF_WEAK_UNAVAILABLE MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = YES IGNORE_PREFIX = OF of_ Index: src/OFApplication.m ================================================================== --- src/OFApplication.m +++ src/OFApplication.m @@ -24,14 +24,17 @@ #import "OFApplication.h" #import "OFString.h" #import "OFArray.h" #import "OFDictionary.h" -#import "OFThread.h" +#ifdef OF_THREADS +# import "OFThread.h" +#endif #import "OFRunLoop.h" #import "autorelease.h" +#import "macros.h" #if defined(__MACH__) && !defined(OF_IOS) # include #elif defined(_WIN32) # include @@ -375,13 +378,18 @@ - (void)run { void *pool = objc_autoreleasePoolPush(); OFRunLoop *runLoop; +#ifdef OF_THREADS [OFThread OF_createMainThread]; runLoop = [OFRunLoop currentRunLoop]; - [OFRunLoop OF_setMainRunLoop]; +#else + runLoop = [[[OFRunLoop alloc] init] autorelease]; +#endif + + [OFRunLoop OF_setMainRunLoop: runLoop]; objc_autoreleasePoolPop(pool); pool = objc_autoreleasePoolPush(); [delegate applicationDidFinishLaunching]; Index: src/OFAutoreleasePool.m ================================================================== --- src/OFAutoreleasePool.m +++ src/OFAutoreleasePool.m @@ -20,28 +20,30 @@ #import "OFAutoreleasePool.h" #import "OFArray.h" #import "macros.h" -#ifndef OF_COMPILER_TLS +#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS) # import "threading.h" # import "OFInitializationFailedException.h" #endif #import "autorelease.h" #define MAX_CACHE_SIZE 0x20 -#ifdef OF_COMPILER_TLS +#if defined(OF_COMPILER_TLS) static __thread OFAutoreleasePool **cache = NULL; -#else +#elif defined(OF_THREADS) static of_tlskey_t cacheKey; +#else +static OFAutoreleasePool **cache = NULL; #endif @implementation OFAutoreleasePool -#ifndef OF_COMPILER_TLS +#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS) + (void)initialize { if (self != [OFAutoreleasePool class]) return; @@ -51,11 +53,11 @@ } #endif + alloc { -#ifndef OF_COMPILER_TLS +#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS) OFAutoreleasePool **cache = of_tlskey_get(cacheKey); #endif if (cache != NULL) { unsigned i; @@ -115,11 +117,11 @@ [self dealloc]; } - (void)dealloc { -#ifndef OF_COMPILER_TLS +#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS) OFAutoreleasePool **cache = of_tlskey_get(cacheKey); #endif if (ignoreRelease) return; @@ -129,11 +131,11 @@ objc_autoreleasePoolPop(pool); if (cache == NULL) { cache = calloc(sizeof(OFAutoreleasePool*), MAX_CACHE_SIZE); -#ifndef OF_COMPILER_TLS +#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS) if (!of_tlskey_set(cacheKey, cache)) { free(cache); cache = NULL; } #endif Index: src/OFBlock.m ================================================================== --- src/OFBlock.m +++ src/OFBlock.m @@ -19,10 +19,11 @@ #include #include #include #if defined(OF_OBJFW_RUNTIME) +# import "runtime.h" # import "runtime-private.h" #elif defined(OF_APPLE_RUNTIME) # import #endif Index: src/OFObject.h ================================================================== --- src/OFObject.h +++ src/OFObject.h @@ -682,10 +682,11 @@ - (void)performSelector: (SEL)selector withObject: (id)object1 withObject: (id)object2 afterDelay: (double)delay; +#ifdef OF_THREADS /*! * @brief Performs the specified selector on the specified thread. * * @param selector The selector to perform * @param thread The thread on which to perform the selector @@ -808,10 +809,11 @@ - (void)performSelector: (SEL)selector onThread: (OFThread*)thread withObject: (id)object1 withObject: (id)object2 afterDelay: (double)delay; +#endif /*! * @brief This method is called when @ref resolveClassMethod: or * @ref resolveInstanceMethod: returned NO. It should return a target * to which the message should be forwarded. Index: src/OFObject.m ================================================================== --- src/OFObject.m +++ src/OFObject.m @@ -24,11 +24,13 @@ #include #import "OFObject.h" #import "OFTimer.h" -#import "OFThread.h" +#ifdef OF_THREADS +# import "OFThread.h" +#endif #import "OFRunLoop.h" #import "OFAutoreleasePool.h" #import "OFAllocFailedException.h" #import "OFEnumerationMutationException.h" @@ -621,10 +623,11 @@ repeats: NO]; objc_autoreleasePoolPop(pool); } +#ifdef OF_THREADS - (void)performSelector: (SEL)selector onThread: (OFThread*)thread waitUntilDone: (BOOL)waitUntilDone { void *pool = objc_autoreleasePoolPush(); @@ -779,10 +782,11 @@ object: object2 repeats: NO]]; objc_autoreleasePoolPop(pool); } +#endif - (const char*)typeEncodingForSelector: (SEL)selector { #if defined(OF_OBJFW_RUNTIME) return objc_get_type_encoding(object_getClass(self), selector); Index: src/OFRunLoop.h ================================================================== --- src/OFRunLoop.h +++ src/OFRunLoop.h @@ -18,21 +18,25 @@ #import "OFStream.h" #import "OFStreamObserver.h" #import "OFTCPSocket.h" @class OFSortedList; +#ifdef OF_THREADS @class OFMutex; +#endif @class OFTimer; @class OFMutableDictionary; /*! * @brief A class providing a run loop for the application and its processes. */ @interface OFRunLoop: OFObject { OFSortedList *timersQueue; +#ifdef OF_THREADS OFMutex *timersQueueLock; +#endif OFStreamObserver *streamObserver; OFMutableDictionary *readQueues; } /*! @@ -47,11 +51,11 @@ * * @return The run loop for the current thread */ + (OFRunLoop*)currentRunLoop; -+ (void)OF_setMainRunLoop; ++ (void)OF_setMainRunLoop: (OFRunLoop*)runLoop; + (void)OF_addAsyncReadForStream: (OFStream*)stream buffer: (void*)buffer length: (size_t)length target: (id)target selector: (SEL)selector; Index: src/OFRunLoop.m ================================================================== --- src/OFRunLoop.m +++ src/OFRunLoop.m @@ -18,13 +18,15 @@ #include #import "OFRunLoop.h" #import "OFDictionary.h" -#import "OFThread.h" +#ifdef OF_THREADS +# import "OFThread.h" +# import "OFMutex.h" +#endif #import "OFSortedList.h" -#import "OFMutex.h" #import "OFTimer.h" #import "OFDate.h" #import "autorelease.h" #import "macros.h" @@ -134,18 +136,20 @@ return [[mainRunLoop retain] autorelease]; } + (OFRunLoop*)currentRunLoop { +#ifdef OF_THREADS return [[OFThread currentThread] runLoop]; +#else + return [self mainRunLoop]; +#endif } -+ (void)OF_setMainRunLoop ++ (void)OF_setMainRunLoop: (OFRunLoop*)runLoop { - void *pool = objc_autoreleasePoolPush(); - mainRunLoop = [[self currentRunLoop] retain]; - objc_autoreleasePoolPop(pool); + mainRunLoop = [runLoop retain]; } #define ADD(type, code) \ void *pool = objc_autoreleasePoolPush(); \ OFRunLoop *runLoop = [self currentRunLoop]; \ @@ -283,11 +287,13 @@ { self = [super init]; @try { timersQueue = [[OFSortedList alloc] init]; +#ifdef OF_THREADS timersQueueLock = [[OFMutex alloc] init]; +#endif streamObserver = [[OFStreamObserver alloc] init]; [streamObserver setDelegate: self]; readQueues = [[OFMutableDictionary alloc] init]; @@ -300,47 +306,57 @@ } - (void)dealloc { [timersQueue release]; +#ifdef OF_THREADS [timersQueueLock release]; +#endif [streamObserver release]; [readQueues release]; [super dealloc]; } - (void)addTimer: (OFTimer*)timer { +#ifdef OF_THREADS [timersQueueLock lock]; @try { +#endif [timersQueue insertObject: timer]; +#ifdef OF_THREADS } @finally { [timersQueueLock unlock]; } +#endif [timer OF_setInRunLoop: self]; [streamObserver cancel]; } - (void)OF_removeTimer: (OFTimer*)timer { +#ifdef OF_THREADS [timersQueueLock lock]; @try { +#endif of_list_object_t *iter; for (iter = [timersQueue firstListObject]; iter != NULL; iter = iter->next) { if ([iter->object isEqual: timer]) { [timersQueue removeListObject: iter]; break; } } +#ifdef OF_THREADS } @finally { [timersQueueLock unlock]; } +#endif } - (void)streamIsReadyForReading: (OFStream*)stream { OFList *queue = [readQueues objectForKey: stream]; @@ -573,12 +589,14 @@ void *pool = objc_autoreleasePoolPush(); OFDate *now = [OFDate date]; OFTimer *timer; OFDate *nextTimer; +#ifdef OF_THREADS [timersQueueLock lock]; @try { +#endif of_list_object_t *listObject = [timersQueue firstListObject]; if (listObject != NULL && [[listObject->object fireDate] compare: now] != @@ -589,23 +607,29 @@ [timersQueue removeListObject: listObject]; [timer OF_setInRunLoop: nil]; } else timer = nil; +#ifdef OF_THREADS } @finally { [timersQueueLock unlock]; } +#endif if ([timer isValid]) [timer fire]; +#ifdef OF_THREADS [timersQueueLock lock]; @try { +#endif nextTimer = [[timersQueue firstObject] fireDate]; +#ifdef OF_THREADS } @finally { [timersQueueLock unlock]; } +#endif /* Watch for stream events until the next timer is due */ if (nextTimer != nil) { double timeout = [nextTimer timeIntervalSinceNow]; Index: src/OFStreamObserver.h ================================================================== --- src/OFStreamObserver.h +++ src/OFStreamObserver.h @@ -26,11 +26,13 @@ @class OFStream; @class OFMutableArray; @class OFMutableDictionary; @class OFDataArray; +#ifdef OF_THREADS @class OFMutex; +#endif /*! * @brief A protocol that needs to be implemented by delegates for * OFStreamObserver. */ @@ -84,11 +86,13 @@ id delegate; int cancelFD[2]; #ifdef _WIN32 struct sockaddr_in cancelAddr; #endif +#ifdef OF_THREADS OFMutex *mutex; +#endif } #ifdef OF_HAVE_PROPERTIES @property (assign) id delegate; #endif Index: src/OFStreamObserver.m ================================================================== --- src/OFStreamObserver.m +++ src/OFStreamObserver.m @@ -186,55 +186,67 @@ delegate = delegate_; } - (void)addStreamForReading: (OFStream*)stream { +#ifdef OF_THREADS [mutex lock]; @try { +#endif int qi = QUEUE_ADD | QUEUE_READ; int fd = [stream fileDescriptorForReading]; [queue addObject: stream]; [queueInfo addItem: &qi]; [queueFDs addItem: &fd]; +#ifdef OF_THREADS } @finally { [mutex unlock]; } +#endif [self cancel]; } - (void)addStreamForWriting: (OFStream*)stream { +#ifdef OF_THREADS [mutex lock]; @try { +#endif int qi = QUEUE_ADD | QUEUE_WRITE; int fd = [stream fileDescriptorForWriting]; [queue addObject: stream]; [queueInfo addItem: &qi]; [queueFDs addItem: &fd]; +#ifdef OF_THREADS } @finally { [mutex unlock]; } +#endif [self cancel]; } - (void)removeStreamForReading: (OFStream*)stream { +#ifdef OF_THREADS [mutex lock]; @try { +#endif int qi = QUEUE_REMOVE | QUEUE_READ; int fd = [stream fileDescriptorForReading]; [queue addObject: stream]; [queueInfo addItem: &qi]; [queueFDs addItem: &fd]; +#ifdef OF_THREADS } @finally { [mutex unlock]; } +#endif #ifndef _WIN32 OF_ENSURE(write(cancelFD[1], "", 1) > 0); #else OF_ENSURE(sendto(cancelFD[1], "", 1, 0, (struct sockaddr*)&cancelAddr, @@ -242,21 +254,25 @@ #endif } - (void)removeStreamForWriting: (OFStream*)stream { +#ifdef OF_THREADS [mutex lock]; @try { +#endif int qi = QUEUE_REMOVE | QUEUE_WRITE; int fd = [stream fileDescriptorForWriting]; [queue addObject: stream]; [queueInfo addItem: &qi]; [queueFDs addItem: &fd]; +#ifdef OF_THREADS } @finally { [mutex unlock]; } +#endif #ifndef _WIN32 OF_ENSURE(write(cancelFD[1], "", 1) > 0); #else OF_ENSURE(sendto(cancelFD[1], "", 1, 0, (struct sockaddr*)&cancelAddr, @@ -288,12 +304,14 @@ abort(); } - (void)OF_processQueue { +#ifdef OF_THREADS [mutex lock]; @try { +#endif OFStream **queueObjects = [queue objects]; int *queueInfoItems = [queueInfo items]; int *queueFDsItems = [queueFDs items]; size_t i, count = [queue count]; @@ -350,13 +368,15 @@ } [queue removeAllObjects]; [queueInfo removeAllItems]; [queueFDs removeAllItems]; +#ifdef OF_THREADS } @finally { [mutex unlock]; } +#endif } - (void)observe { [self observeWithTimeout: -1]; Index: src/OFTCPSocket.h ================================================================== --- src/OFTCPSocket.h +++ src/OFTCPSocket.h @@ -128,10 +128,11 @@ * @param port The port on the host to connect to */ - (void)connectToHost: (OFString*)host port: (uint16_t)port; +#ifdef OF_THREADS /*! * @brief Asyncronously connect the OFTCPSocket to the specified destination. * * @param host The host to connect to * @param port The port on the host to connect to @@ -143,11 +144,11 @@ - (void)asyncConnectToHost: (OFString*)host port: (uint16_t)port target: (id)target selector: (SEL)selector; -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS /*! * @brief Asyncronously connect the OFTCPSocket to the specified destination. * * @param host The host to connect to * @param port The port on the host to connect to @@ -154,10 +155,11 @@ * @param block The block to execute once the connection has been established */ - (void)asyncConnectToHost: (OFString*)host port: (uint16_t)port block: (of_tcpsocket_async_connect_block_t)block; +# endif #endif /*! * @brief Bind the socket on the specified port and host. * Index: src/OFTCPSocket.m ================================================================== --- src/OFTCPSocket.m +++ src/OFTCPSocket.m @@ -33,11 +33,13 @@ #endif #import "OFTCPSocket.h" #import "OFTCPSocket+SOCKS5.h" #import "OFString.h" -#import "OFThread.h" +#ifdef OF_THREADS +# import "OFThread.h" +#endif #import "OFTimer.h" #import "OFRunLoop.h" #import "OFAcceptFailedException.h" #import "OFAlreadyConnectedException.h" @@ -77,37 +79,38 @@ Class of_tls_socket_class = Nil; static OFString *defaultSOCKS5Host = nil; static uint16_t defaultSOCKS5Port = 1080; +#ifdef OF_THREADS @interface OFTCPSocket_ConnectThread: OFThread { OFThread *sourceThread; OFTCPSocket *sock; OFString *host; uint16_t port; id target; SEL selector; -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS of_tcpsocket_async_connect_block_t connectBlock; -#endif +# endif OFException *exception; } - initWithSourceThread: (OFThread*)sourceThread socket: (OFTCPSocket*)socket host: (OFString*)host port: (uint16_t)port target: (id)target selector: (SEL)selector; -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS - initWithSourceThread: (OFThread*)sourceThread socket: (OFTCPSocket*)socket host: (OFString*)host port: (uint16_t)port block: (of_tcpsocket_async_connect_block_t)block; -#endif +# endif @end @implementation OFTCPSocket_ConnectThread - initWithSourceThread: (OFThread*)sourceThread_ socket: (OFTCPSocket*)sock_ @@ -131,11 +134,11 @@ } return self; } -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS - initWithSourceThread: (OFThread*)sourceThread_ socket: (OFTCPSocket*)sock_ host: (OFString*)host_ port: (uint16_t)port_ block: (of_tcpsocket_async_connect_block_t)block_ @@ -153,43 +156,43 @@ @throw e; } return self; } -#endif +# endif - (void)dealloc { [sourceThread release]; [sock release]; [host release]; [target release]; -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS [connectBlock release]; -#endif +# endif [exception release]; [super dealloc]; } - (void)didConnect { [self join]; -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS if (connectBlock != NULL) connectBlock(sock, exception); else { -#endif +# endif void (*func)(id, SEL, OFTCPSocket*, OFException*) = (void(*)(id, SEL, OFTCPSocket*, OFException*))[target methodForSelector: selector]; func(target, selector, sock, exception); -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS } -#endif +# endif } - (id)main { void *pool = objc_autoreleasePoolPush(); @@ -208,10 +211,11 @@ objc_autoreleasePoolPop(pool); return nil; } @end +#endif @implementation OFTCPSocket #if defined(OF_THREADS) && !defined(HAVE_THREADSAFE_GETADDRINFO) + (void)initialize { @@ -423,10 +427,11 @@ if (SOCKS5Host != nil) [self OF_SOCKS5ConnectToHost: destinationHost port: destinationPort]; } +#ifdef OF_THREADS - (void)asyncConnectToHost: (OFString*)host port: (uint16_t)port target: (id)target selector: (SEL)selector { @@ -441,11 +446,11 @@ selector: selector] autorelease] start]; objc_autoreleasePoolPop(pool); } -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS - (void)asyncConnectToHost: (OFString*)host port: (uint16_t)port block: (of_tcpsocket_async_connect_block_t)block { void *pool = objc_autoreleasePoolPush(); @@ -457,10 +462,11 @@ port: port block: block] autorelease] start]; objc_autoreleasePoolPop(pool); } +# endif #endif - (uint16_t)bindToHost: (OFString*)host port: (uint16_t)port { Index: src/OFTimer.h ================================================================== --- src/OFTimer.h +++ src/OFTimer.h @@ -16,12 +16,14 @@ #import "OFObject.h" @class OFTimer; @class OFDate; -@class OFCondition; @class OFRunLoop; +#ifdef OF_THREADS +@class OFCondition; +#endif #ifdef OF_HAVE_BLOCKS typedef void (^of_timer_block_t)(OFTimer*); #endif @@ -37,12 +39,15 @@ uint8_t arguments; BOOL repeats; #ifdef OF_HAVE_BLOCKS of_timer_block_t block; #endif - BOOL isValid, done; + BOOL isValid; +#ifdef OF_THREADS OFCondition *condition; + BOOL done; +#endif OFRunLoop *inRunLoop; } #ifdef OF_HAVE_PROPERTIES @property (retain) OFDate *fireDate; @@ -308,12 +313,14 @@ * @return The time interval in which the timer will repeat, if it is a * repeating timer */ - (double)timeInterval; +#ifdef OF_THREADS /*! * @brief Waits until the timer fired. */ - (void)waitUntilDone; +#endif - (void)OF_setInRunLoop: (OFRunLoop*)inRunLoop; @end Index: src/OFTimer.m ================================================================== --- src/OFTimer.m +++ src/OFTimer.m @@ -21,11 +21,13 @@ #include #import "OFTimer.h" #import "OFDate.h" #import "OFRunLoop.h" -#import "OFCondition.h" +#ifdef OF_THREADS +# import "OFCondition.h" +#endif #import "OFInvalidArgumentException.h" #import "autorelease.h" #import "macros.h" @@ -233,11 +235,13 @@ object1 = [object1_ retain]; object2 = [object2_ retain]; arguments = arguments_; repeats = repeats_; isValid = YES; +#ifdef OF_THREADS condition = [[OFCondition alloc] init]; +#endif } @catch (id e) { [self release]; @throw e; } @@ -307,11 +311,13 @@ fireDate = [fireDate_ retain]; interval = interval_; repeats = repeats_; block = [block_ copy]; isValid = YES; +# ifdef OF_THREADS condition = [[OFCondition alloc] init]; +# endif } @catch (id e) { [self release]; @throw e; } @@ -332,11 +338,13 @@ [object1 release]; [object2 release]; #ifdef OF_HAVE_BLOCKS [block release]; #endif +#ifdef OF_THREADS [condition release]; +#endif [super dealloc]; } - (of_comparison_result_t)compare: (id )object_ @@ -378,17 +386,19 @@ } #ifdef OF_HAVE_BLOCKS } #endif +#ifdef OF_THREADS [condition lock]; @try { done = YES; [condition signal]; } @finally { [condition unlock]; } +#endif if (repeats && isValid) { OFDate *old = fireDate; fireDate = [[OFDate alloc] initWithTimeIntervalSinceNow: interval]; @@ -436,10 +446,11 @@ - (BOOL)isValid { return isValid; } +#ifdef OF_THREADS - (void)waitUntilDone { [condition lock]; @try { if (done) { @@ -450,11 +461,12 @@ [condition wait]; } @finally { [condition unlock]; } } +#endif - (void)OF_setInRunLoop: (OFRunLoop*)inRunLoop_ { OF_SETTER(inRunLoop, inRunLoop_, YES, 0) } @end Index: src/autorelease.m ================================================================== --- src/autorelease.m +++ src/autorelease.m @@ -20,24 +20,30 @@ #include #import "OFObject.h" #import "OFSystemInfo.h" -#ifndef OF_COMPILER_TLS +#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS) # import "threading.h" #endif #import "macros.h" #import "autorelease.h" -#ifdef OF_COMPILER_TLS +#if defined(OF_COMPILER_TLS) static __thread id *objects = NULL; static __thread id *top = NULL; static __thread size_t size = 0; -#else +#elif defined(OF_THREADS) static of_tlskey_t objectsKey, topKey, sizeKey; +#else +static id *objects = NULL; +static id *top = NULL; +static size_t size = 0; +#endif +#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS) static void __attribute__((constructor)) init(void) { OF_ENSURE(of_tlskey_new(&objectsKey)); OF_ENSURE(of_tlskey_new(&topKey)); @@ -46,11 +52,11 @@ #endif void* objc_autoreleasePoolPush() { -#ifndef OF_COMPILER_TLS +#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS) id *top = of_tlskey_get(topKey); id *objects = of_tlskey_get(objectsKey); #endif ptrdiff_t offset = top - objects; @@ -58,11 +64,11 @@ } void objc_autoreleasePoolPop(void *offset) { -#ifndef OF_COMPILER_TLS +#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS) id *top = of_tlskey_get(topKey); id *objects = of_tlskey_get(objectsKey); #endif id *pool = objects + (ptrdiff_t)offset; id *iter; @@ -77,20 +83,20 @@ objects = NULL; top = NULL; } -#ifndef OF_COMPILER_TLS +#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS) OF_ENSURE(of_tlskey_set(topKey, top)); OF_ENSURE(of_tlskey_set(objectsKey, objects)); #endif } id _objc_rootAutorelease(id object) { -#ifndef OF_COMPILER_TLS +#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS) id *top = of_tlskey_get(topKey); id *objects = of_tlskey_get(objectsKey); size_t size = (size_t)(uintptr_t)of_tlskey_get(sizeKey); #endif @@ -99,11 +105,11 @@ OF_ENSURE((objects = malloc(size)) != NULL); top = objects; -#ifndef OF_COMPILER_TLS +#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS) OF_ENSURE(of_tlskey_set(objectsKey, objects)); OF_ENSURE(of_tlskey_set(sizeKey, (void*)(uintptr_t)size)); #endif } @@ -111,11 +117,11 @@ ptrdiff_t diff = top - objects; size += [OFSystemInfo pageSize]; OF_ENSURE((objects = realloc(objects, size)) != NULL); -#ifndef OF_COMPILER_TLS +#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS) OF_ENSURE(of_tlskey_set(objectsKey, objects)); OF_ENSURE(of_tlskey_set(sizeKey, (void*)(uintptr_t)size)); #endif top = objects + diff; @@ -122,11 +128,11 @@ } *top = object; top++; -#ifndef OF_COMPILER_TLS +#if !defined(OF_COMPILER_TLS) && defined(OF_THREADS) OF_ENSURE(of_tlskey_set(topKey, top)); #endif return object; } Index: src/exceptions/Makefile ================================================================== --- src/exceptions/Makefile +++ src/exceptions/Makefile @@ -9,14 +9,10 @@ OFAlreadyConnectedException.m \ OFBindFailedException.m \ OFChangeDirectoryFailedException.m \ OFChangeFileModeFailedException.m \ OFChangeFileOwnerFailedException.m \ - OFConditionBroadcastFailedException.m \ - OFConditionSignalFailedException.m \ - OFConditionStillWaitingException.m \ - OFConditionWaitFailedException.m \ OFConnectionFailedException.m \ OFCopyFileFailedException.m \ OFCreateDirectoryFailedException.m \ OFDeleteDirectoryFailedException.m \ OFDeleteFileFailedException.m \ @@ -45,21 +41,26 @@ OFRenameFileFailedException.m \ OFSeekFailedException.m \ OFSetOptionFailedException.m \ OFStillLockedException.m \ OFSymlinkFailedException.m \ - OFThreadJoinFailedException.m \ - OFThreadStartFailedException.m \ - OFThreadStillRunningException.m \ OFTruncatedDataException.m \ OFUnboundNamespaceException.m \ OFUnlockFailedException.m \ OFUnsupportedProtocolException.m \ OFUnsupportedVersionException.m \ - OFWriteFailedException.m + OFWriteFailedException.m \ + ${USE_SRCS_THREADS} +SRCS_THREADS = OFConditionBroadcastFailedException.m \ + OFConditionSignalFailedException.m \ + OFConditionStillWaitingException.m \ + OFConditionWaitFailedException.m \ + OFThreadJoinFailedException.m \ + OFThreadStartFailedException.m \ + OFThreadStillRunningException.m INCLUDES = ${SRCS:.m=.h} include ../../buildsys.mk CPPFLAGS += -I. -I.. -I../.. -I../runtime LD = ${OBJC} Index: src/runtime/Makefile ================================================================== --- src/runtime/Makefile +++ src/runtime/Makefile @@ -15,12 +15,13 @@ protocol.m \ selector.m \ sparsearray.m \ static-instances.m \ synchronized.m \ - threading.m + ${USE_SRCS_THREADS} +SRCS_THREADS = threading.m INCLUDES = runtime.h include ../../buildsys.mk CPPFLAGS += -I. -I.. -I../.. LD = ${OBJC} Index: src/runtime/runtime-private.h ================================================================== --- src/runtime/runtime-private.h +++ src/runtime/runtime-private.h @@ -12,11 +12,11 @@ * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ -#import "threading.h" +#include "config.h" struct objc_abi_class { struct objc_abi_class *metaclass; const char *superclass; const char *name; @@ -121,16 +121,10 @@ const void *buckets[256]; BOOL empty; }; #endif -typedef struct { - of_mutex_t mutex; - of_thread_t owner; - int count; -} objc_mutex_t; - extern void objc_register_all_categories(struct objc_abi_symtab*); extern struct objc_category** objc_categories_for_class(Class); extern void objc_free_all_categories(void); extern void objc_initialize_class(Class); extern void objc_update_dtable(Class); @@ -153,13 +147,19 @@ const void*); extern void objc_sparsearray_free(struct objc_sparsearray*); extern void objc_sparsearray_cleanup(void); extern void objc_init_static_instances(struct objc_abi_symtab*); extern void __objc_exec_class(struct objc_abi_module*); +#ifdef OF_THREADS extern void objc_global_mutex_lock(void); extern void objc_global_mutex_unlock(void); extern void objc_global_mutex_free(void); +#else +# define objc_global_mutex_lock() +# define objc_global_mutex_unlock() +# define objc_global_mutex_free() +#endif static inline void* objc_sparsearray_get(const struct objc_sparsearray *s, uint32_t idx) { #ifdef OF_SELUID24 Index: src/runtime/synchronized.m ================================================================== --- src/runtime/synchronized.m +++ src/runtime/synchronized.m @@ -19,11 +19,13 @@ #include #include #import "runtime.h" #import "runtime-private.h" -#import "threading.h" + +#ifdef OF_THREADS +# import "threading.h" struct lock_s { id object; int count; of_rmutex_t rmutex; @@ -36,14 +38,16 @@ init(void) { if (!of_mutex_new(&mutex)) OBJC_ERROR("Failed to create mutex!") } +#endif int objc_sync_enter(id object) { +#ifdef OF_THREADS struct lock_s *lock; if (!of_mutex_lock(&mutex)) OBJC_ERROR("Failed to lock mutex!"); @@ -79,17 +83,19 @@ if (!of_mutex_unlock(&mutex)) OBJC_ERROR("Failed to unlock mutex!"); if (!of_rmutex_lock(&lock->rmutex)) OBJC_ERROR("Failed to lock mutex!"); +#endif return 0; } int objc_sync_exit(id object) { +#ifdef OF_THREADS struct lock_s *lock, *last = NULL; if (!of_mutex_lock(&mutex)) OBJC_ERROR("Failed to lock mutex!"); @@ -119,6 +125,9 @@ return 0; } OBJC_ERROR("objc_sync_exit() was called for an object not locked!"); +#else + return 0; +#endif }