Index: ObjFW.xcodeproj/project.pbxproj ================================================================== --- ObjFW.xcodeproj/project.pbxproj +++ ObjFW.xcodeproj/project.pbxproj @@ -45,10 +45,11 @@ 4B067FC2177BA6F900B8CFDA /* OFCreateSymbolicLinkFailedException.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B067FB6177BA6F900B8CFDA /* OFCreateSymbolicLinkFailedException.m */; }; 4B11005C14329B9A003A45D8 /* OFXMLNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B11005A14329B9A003A45D8 /* OFXMLNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B11005D14329B9A003A45D8 /* OFXMLNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B11005B14329B9A003A45D8 /* OFXMLNode.m */; }; 4B141BA415FCDF74000C21A8 /* OFSortedList.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B141BA215FCDF74000C21A8 /* OFSortedList.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B141BA515FCDF74000C21A8 /* OFSortedList.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B141BA315FCDF74000C21A8 /* OFSortedList.m */; }; + 4B1473CB17E6391900B46BB8 /* OFAutoreleasePool+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1473CA17E6391900B46BB8 /* OFAutoreleasePool+Private.h */; }; 4B17FF73133A2A76003E6DCD /* OFException.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B17FF71133A28FC003E6DCD /* OFException.m */; }; 4B17FF74133A2AAB003E6DCD /* OFException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B17FF70133A28FC003E6DCD /* OFException.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B17FF77133A2B18003E6DCD /* OFNotImplementedException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B17FF75133A2B18003E6DCD /* OFNotImplementedException.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B17FF78133A2B18003E6DCD /* OFNotImplementedException.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B17FF76133A2B18003E6DCD /* OFNotImplementedException.m */; }; 4B17FF7B133A2C15003E6DCD /* OFOutOfRangeException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B17FF79133A2C14003E6DCD /* OFOutOfRangeException.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -487,10 +488,11 @@ 4B0D249511DFAA3D00ED6FFC /* OFXMLElementBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFXMLElementBuilder.m; path = src/OFXMLElementBuilder.m; sourceTree = ""; }; 4B11005A14329B9A003A45D8 /* OFXMLNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFXMLNode.h; path = src/OFXMLNode.h; sourceTree = ""; }; 4B11005B14329B9A003A45D8 /* OFXMLNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFXMLNode.m; path = src/OFXMLNode.m; sourceTree = ""; }; 4B141BA215FCDF74000C21A8 /* OFSortedList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFSortedList.h; path = src/OFSortedList.h; sourceTree = ""; }; 4B141BA315FCDF74000C21A8 /* OFSortedList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSortedList.m; path = src/OFSortedList.m; sourceTree = ""; }; + 4B1473CA17E6391900B46BB8 /* OFAutoreleasePool+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "OFAutoreleasePool+Private.h"; path = "src/OFAutoreleasePool+Private.h"; sourceTree = ""; }; 4B175C1D116D130B003C99CB /* OFApplication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFApplication.h; path = src/OFApplication.h; sourceTree = ""; }; 4B175C1E116D130B003C99CB /* OFApplication.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFApplication.m; path = src/OFApplication.m; sourceTree = ""; }; 4B17FF70133A28FC003E6DCD /* OFException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFException.h; path = src/exceptions/OFException.h; sourceTree = ""; }; 4B17FF71133A28FC003E6DCD /* OFException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFException.m; path = src/exceptions/OFException.m; sourceTree = ""; }; 4B17FF75133A2B18003E6DCD /* OFNotImplementedException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFNotImplementedException.h; path = src/exceptions/OFNotImplementedException.h; sourceTree = ""; }; @@ -1111,10 +1113,11 @@ 4B9BB7BA141CDE2D000AD1CC /* OFArray_adjacentSubarray.m */, 4B9BB7BB141CDE2D000AD1CC /* OFArray_subarray.h */, 4B9BB7BC141CDE2D000AD1CC /* OFArray_subarray.m */, 4B67995C1099E7C50041064A /* OFAutoreleasePool.h */, 4B67995D1099E7C50041064A /* OFAutoreleasePool.m */, + 4B1473CA17E6391900B46BB8 /* OFAutoreleasePool+Private.h */, 4BD86D801237A6C600ED9912 /* OFBlock.h */, 4BD86D811237A6C600ED9912 /* OFBlock.m */, 4BAF5F46123460C900F4E111 /* OFCollection.h */, 4B6743F7163C395900EB1E59 /* OFCondition.h */, 4B6743F8163C395900EB1E59 /* OFCondition.m */, @@ -1566,10 +1569,11 @@ 4BA4846215CC9F1E00D75360 /* OFUnsupportedVersionException.h in Headers */, 4B55A116133AC24600B58A93 /* OFWriteFailedException.h in Headers */, 4B55A109133AC05100B58A93 /* common.h in Headers */, 4B2B3E7D140D430500EC2F7C /* OFArray_adjacent.h in Headers */, 4B9BB7BD141CDE2D000AD1CC /* OFArray_adjacentSubarray.h in Headers */, + 4B1473CB17E6391900B46BB8 /* OFAutoreleasePool+Private.h in Headers */, 4BA85BCA140ECCE800E91D51 /* OFCountedSet_hashtable.h in Headers */, 4B2B3E7F140D430500EC2F7C /* OFDictionary_hashtable.h in Headers */, 4B2B3E81140D430500EC2F7C /* OFMutableArray_adjacent.h in Headers */, 4B2B3E83140D430500EC2F7C /* OFMutableDictionary_hashtable.h in Headers */, 4BA85BCC140ECCE800E91D51 /* OFMutableSet_hashtable.h in Headers */, ADDED src/OFAutoreleasePool+Private.h Index: src/OFAutoreleasePool+Private.h ================================================================== --- src/OFAutoreleasePool+Private.h +++ src/OFAutoreleasePool+Private.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * 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 "OFAutoreleasePool.h" + +#import "macros.h" + +@interface OFAutoreleasePool (OF_PRIVATE_CATEGORY) ++ (void)OF_handleThreadTermination; +- (void)OF_super_dealloc; +@end Index: src/OFAutoreleasePool.m ================================================================== --- src/OFAutoreleasePool.m +++ src/OFAutoreleasePool.m @@ -17,10 +17,11 @@ #include "config.h" #include #import "OFAutoreleasePool.h" +#import "OFAutoreleasePool+Private.h" #import "macros.h" #if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) # import "threading.h" @@ -75,10 +76,26 @@ + (id)addObject: (id)object { return _objc_rootAutorelease(object); } + ++ (void)OF_handleThreadTermination +{ +#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) + OFAutoreleasePool **cache = of_tlskey_get(cacheKey); +#endif + size_t i; + + if (cache != NULL) { + for (i = 0; i < MAX_CACHE_SIZE; i++) + [cache[i] OF_super_dealloc]; + + free(cache); + cache = NULL; + } +} - init { self = [super init]; @@ -113,10 +130,15 @@ - (void)drain { [self dealloc]; } + +- (void)OF_super_dealloc +{ + [super dealloc]; +} - (void)dealloc { #if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) OFAutoreleasePool **cache = of_tlskey_get(cacheKey); Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -2167,11 +2167,11 @@ - (OFString*)stringByDeletingPathExtension { void *pool; OFMutableArray *components; - OFString *fileName, *ret; + OFString *ret, *fileName; size_t pos; if ([self length] == 0) return [[self copy] autorelease]; Index: src/OFThread.h ================================================================== --- src/OFThread.h +++ src/OFThread.h @@ -59,10 +59,11 @@ enum { OF_THREAD_NOT_RUNNING, OF_THREAD_RUNNING, OF_THREAD_WAITING_FOR_JOIN } _running; + void *_pool; # ifdef OF_HAVE_BLOCKS of_thread_block_t _threadBlock; # endif id _returnValue; OFRunLoop *_runLoop; Index: src/OFThread.m ================================================================== --- src/OFThread.m +++ src/OFThread.m @@ -42,10 +42,11 @@ #import "OFRunLoop.h" #import "OFList.h" #import "OFDate.h" #import "OFDictionary.h" #import "OFAutoreleasePool.h" +#import "OFAutoreleasePool+Private.h" #ifdef _WIN32 # include #endif @@ -77,11 +78,11 @@ if (!of_tlskey_set(threadSelfKey, thread)) @throw [OFInitializationFailedException exceptionWithClass: [thread class]]; - objc_autoreleasePoolPush(); + thread->_pool = objc_autoreleasePoolPush(); /* * Nasty workaround for thread implementations which can't return a * value on join. */ @@ -94,18 +95,12 @@ [thread handleTermination]; thread->_running = OF_THREAD_WAITING_FOR_JOIN; -# 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 + objc_autoreleasePoolPop(thread->_pool); + [OFAutoreleasePool OF_handleThreadTermination]; [thread release]; return 0; } @@ -233,18 +228,12 @@ [thread handleTermination]; thread->_running = OF_THREAD_WAITING_FOR_JOIN; } -# 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 + objc_autoreleasePoolPop(thread->_pool); + [OFAutoreleasePool OF_handleThreadTermination]; [thread release]; of_thread_exit(); }