Index: src/OFThread.h ================================================================== --- src/OFThread.h +++ src/OFThread.h @@ -12,10 +12,12 @@ * 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. */ + +#include #import "OFObject.h" #ifdef OF_HAVE_THREADS # import "threading.h" @@ -70,10 +72,11 @@ } _running; void *_pool; # ifdef OF_HAVE_BLOCKS of_thread_block_t _Nullable _threadBlock; # endif + jmp_buf _exitEnv; id _returnValue; OFRunLoop *_Nullable _runLoop; OFMutableDictionary *_threadDictionary; @private OFString *_Nullable _name; Index: src/OFThread.m ================================================================== --- src/OFThread.m +++ src/OFThread.m @@ -133,18 +133,20 @@ else of_thread_set_name(object_getClassName(thread)); /* * Nasty workaround for thread implementations which can't return a - * pointer on join. + * pointer on join, or don't have a way to exit a thread. */ + if (setjmp(thread->_exitEnv) == 0) { # ifdef OF_HAVE_BLOCKS - if (thread->_threadBlock != NULL) - thread->_returnValue = [thread->_threadBlock() retain]; - else + if (thread->_threadBlock != NULL) + thread->_returnValue = [thread->_threadBlock() retain]; + else # endif - thread->_returnValue = [[thread main] retain]; + thread->_returnValue = [[thread main] retain]; + } [thread handleTermination]; thread->_running = OF_THREAD_WAITING_FOR_JOIN; @@ -325,24 +327,14 @@ + (void)terminateWithObject: (id)object { OFThread *thread = of_tlskey_get(threadSelfKey); - if (thread != nil) { - thread->_returnValue = [object retain]; - - [thread handleTermination]; - - thread->_running = OF_THREAD_WAITING_FOR_JOIN; - objc_autoreleasePoolPop(thread->_pool); - } - - [OFAutoreleasePool of_handleThreadTermination]; - - [thread release]; - - of_thread_exit(); + OF_ENSURE(thread != nil); + + thread->_returnValue = [object retain]; + longjmp(thread->_exitEnv, 1); } + (void)setName: (OFString *)name { [OFThread currentThread].name = name; Index: src/threading.h ================================================================== --- src/threading.h +++ src/threading.h @@ -94,11 +94,10 @@ extern bool of_thread_new(of_thread_t *thread, void (*function)(id), id object, const of_thread_attr_t *attr); extern void of_thread_set_name(const char *name); extern bool of_thread_join(of_thread_t thread); extern bool of_thread_detach(of_thread_t thread); -extern void OF_NO_RETURN_FUNC of_thread_exit(void); extern void of_once(of_once_t *control, void (*func)(void)); extern bool of_tlskey_new(of_tlskey_t *key); extern bool of_tlskey_free(of_tlskey_t key); extern bool of_mutex_new(of_mutex_t *mutex); extern bool of_mutex_lock(of_mutex_t *mutex); Index: src/threading_pthread.m ================================================================== --- src/threading_pthread.m +++ src/threading_pthread.m @@ -177,18 +177,10 @@ of_thread_detach(of_thread_t thread) { return (pthread_detach(thread) == 0); } -void OF_NO_RETURN_FUNC -of_thread_exit(void) -{ - pthread_exit(NULL); - - OF_UNREACHABLE -} - void of_thread_set_name(const char *name) { #if defined(OF_HAIKU) rename_thread(find_thread(NULL), name); Index: src/threading_winapi.m ================================================================== --- src/threading_winapi.m +++ src/threading_winapi.m @@ -76,18 +76,10 @@ { /* FIXME */ return true; } -void OF_NO_RETURN_FUNC -of_thread_exit(void) -{ - ExitThread(0); - - OF_UNREACHABLE -} - void of_thread_set_name(const char *name) { }