Index: src/OFApplication.m ================================================================== --- src/OFApplication.m +++ src/OFApplication.m @@ -294,16 +294,18 @@ #undef REGISTER_SIGNAL } - (void)run { - void *pool; + void *pool = objc_autoreleasePoolPush(); OFRunLoop *runLoop; [OFThread OF_createMainThread]; runLoop = [OFRunLoop currentRunLoop]; [OFRunLoop OF_setMainRunLoop]; + + objc_autoreleasePoolPop(pool); pool = objc_autoreleasePoolPush(); [delegate applicationDidFinishLaunching]; objc_autoreleasePoolPop(pool); Index: src/OFAutoreleasePool.h ================================================================== --- src/OFAutoreleasePool.h +++ src/OFAutoreleasePool.h @@ -37,12 +37,10 @@ * \param object The object to add to the autorelease pool * \return The object */ + (id)addObject: (id)object; -+ (void)OF_releaseAll; - /** * \brief Releases all objects in the autorelease pool. * * This does not free the memory allocated to store pointers to the objects in * the pool, so reusing the pool does not allocate any memory until the previous Index: src/OFAutoreleasePool.m ================================================================== --- src/OFAutoreleasePool.m +++ src/OFAutoreleasePool.m @@ -33,37 +33,23 @@ #import "autorelease.h" #define MAX_CACHE_SIZE 0x20 #ifdef OF_COMPILER_TLS -static __thread void *first = NULL; static __thread OFAutoreleasePool **cache = NULL; #else -static of_tlskey_t firstKey, cacheKey; -#endif - -id -of_autorelease(id object) -{ -#ifndef OF_COMPILER_TLS - void *first = of_tlskey_get(firstKey); -#endif - - if (first == NULL) - [[OFAutoreleasePool alloc] init]; - - return _objc_rootAutorelease(object); -} +static of_tlskey_t cacheKey; +#endif @implementation OFAutoreleasePool #ifndef OF_COMPILER_TLS + (void)initialize { if (self != [OFAutoreleasePool class]) return; - if (!of_tlskey_new(&firstKey) || !of_tlskey_new(&cacheKey)) + if (!of_tlskey_new(&cacheKey)) @throw [OFInitializationFailedException exceptionWithClass: self]; } #endif @@ -88,40 +74,20 @@ return [super alloc]; } + (id)addObject: (id)object { - return of_autorelease(object); -} - -+ (void)OF_releaseAll -{ -#ifndef OF_COMPILER_TLS - void *first = of_tlskey_get(firstKey); -#endif - - objc_autoreleasePoolPop(first); + return _objc_rootAutorelease(object); } - init { self = [super init]; @try { -#ifndef OF_COMPILER_TLS - void *first = of_tlskey_get(firstKey); -#endif - pool = objc_autoreleasePoolPush(); - if (first == NULL) -#ifdef OF_COMPILER_TLS - first = pool; -#else - OF_ENSURE(of_tlskey_set(firstKey, pool)); -#endif - _objc_rootAutorelease(self); } @catch (id e) { [self release]; @throw e; } @@ -160,18 +126,10 @@ if (ignoreRelease) return; ignoreRelease = YES; -#ifdef OF_COMPILER_TLS - if (first == pool) - first = NULL; -#else - if (of_tlskey_get(firstKey) == pool) - OF_ENSURE(of_tlskey_set(firstKey, NULL)); -#endif - objc_autoreleasePoolPop(pool); if (cache == NULL) { cache = calloc(sizeof(OFAutoreleasePool*), MAX_CACHE_SIZE); Index: src/OFObject.m ================================================================== --- src/OFObject.m +++ src/OFObject.m @@ -941,11 +941,11 @@ #endif } - autorelease { - return of_autorelease(self); + return _objc_rootAutorelease(self); } - self { return self; Index: src/OFThread.m ================================================================== --- src/OFThread.m +++ src/OFThread.m @@ -52,10 +52,11 @@ #import "OFThreadJoinFailedException.h" #import "OFThreadStartFailedException.h" #import "OFThreadStillRunningException.h" #import "atomic.h" +#import "autorelease.h" #import "threading.h" static OFList *TLSKeys; static of_tlskey_t threadSelfKey; static OFThread *mainThread; @@ -62,34 +63,42 @@ static id call_main(id object) { OFThread *thread = (OFThread*)object; + void *pool; if (!of_tlskey_set(threadSelfKey, thread)) @throw [OFInitializationFailedException exceptionWithClass: [thread class]]; + + pool = objc_autoreleasePoolPush(); /* * Nasty workaround for thread implementations which can't return a * value on join. */ #ifdef OF_HAVE_BLOCKS if (thread->block != NULL) thread->returnValue = [thread->block(thread->object) retain]; else - thread->returnValue = [[thread main] retain]; -#else - thread->returnValue = [[thread main] retain]; #endif + thread->returnValue = [[thread main] retain]; [thread handleTermination]; thread->running = OF_THREAD_WAITING_FOR_JOIN; [OFTLSKey callAllDestructors]; - [OFAutoreleasePool OF_releaseAll]; +#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 [thread release]; return 0; } @@ -222,11 +231,18 @@ thread->running = OF_THREAD_WAITING_FOR_JOIN; } [OFTLSKey callAllDestructors]; - [OFAutoreleasePool OF_releaseAll]; +#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 [thread release]; of_thread_exit(); } Index: src/exceptions/OFException.m ================================================================== --- src/exceptions/OFException.m +++ src/exceptions/OFException.m @@ -60,11 +60,11 @@ { if (description != nil) return description; description = [[OFString alloc] initWithFormat: - @"An exception of class %@ occurred in class %@", + @"An exception of class %@ occurred in class %@!", object_getClass(self), inClass]; return description; } @end