@@ -15,45 +15,87 @@ */ #include "config.h" #include + +#include #import "OFAutoreleasePool.h" #import "OFArray.h" + +#ifndef OF_COMPILER_TLS +# import "threading.h" + +# import "OFInitializationFailedException.h" +#endif #import "OFNotImplementedException.h" extern id _objc_rootAutorelease(id); extern void* objc_autoreleasePoolPush(void); extern void objc_autoreleasePoolPop(void*); +#ifdef OF_COMPILER_TLS static __thread void *first = NULL; +#else +static of_tlskey_t firstKey; +#endif @implementation OFAutoreleasePool +#ifndef OF_COMPILER_TLS ++ (void)initialize +{ + if (self != [OFAutoreleasePool class]) + return; + + if (!of_tlskey_new(&firstKey)) + @throw [OFInitializationFailedException + exceptionWithClass: self]; +} +#endif + + (id)addObject: (id)object { +#ifndef OF_COMPILER_TLS + void *first = of_tlskey_get(firstKey); +#endif + if (first == NULL) [[OFAutoreleasePool alloc] init]; return _objc_rootAutorelease(object); } + (void)_releaseAll { +#ifndef OF_COMPILER_TLS + void *first = of_tlskey_get(firstKey); +#endif + objc_autoreleasePoolPop(first); } - 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 + if (!of_tlskey_set(firstKey, pool)) + @throw [OFInitializationFailedException + exceptionWithClass: [self class]]; +#endif _objc_rootAutorelease(self); } @catch (id e) { [self release]; @throw e; @@ -89,12 +131,17 @@ if (ignoreRelease) return; ignoreRelease = YES; +#ifdef OF_COMPILER_TLS if (first == pool) first = NULL; +#else + if (of_tlskey_get(firstKey) == pool) + assert(of_tlskey_set(firstKey, NULL)); +#endif objc_autoreleasePoolPop(pool); [super dealloc]; }