Index: src/OFThread.m ================================================================== --- src/OFThread.m +++ src/OFThread.m @@ -78,11 +78,11 @@ # import "threading.h" static of_tlskey_t threadSelfKey; static OFThread *mainThread; -static id +static void callMain(id object) { OFThread *thread = (OFThread*)object; if (!of_tlskey_set(threadSelfKey, thread)) @@ -108,12 +108,10 @@ objc_autoreleasePoolPop(thread->_pool); [OFAutoreleasePool OF_handleThreadTermination]; [thread release]; - - return 0; } #endif @implementation OFThread #ifdef OF_HAVE_THREADS Index: src/threading.h ================================================================== --- src/threading.h +++ src/threading.h @@ -95,11 +95,11 @@ # error of_thread_is_current not implemented! # error of_thread_current not implemented! #endif extern bool of_thread_attr_init(of_thread_attr_t *attr); -extern bool of_thread_new(of_thread_t *thread, id (*function)(id), id data, +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(of_thread_t thread, 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 of_thread_exit(void); Index: src/threading_pthread.m ================================================================== --- src/threading_pthread.m +++ src/threading_pthread.m @@ -11,10 +11,28 @@ * 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. */ + +struct thread_ctx { + void (*function)(id object); + id object; +}; + +static void* +function_wrapper(void *data) +{ + struct thread_ctx *ctx = data; + + pthread_cleanup_push(free, data); + + ctx->function(ctx->object); + + pthread_cleanup_pop(1); + return NULL; +} bool of_thread_attr_init(of_thread_attr_t *attr) { pthread_attr_t pattr; @@ -50,20 +68,22 @@ return true; } bool -of_thread_new(of_thread_t *thread, id (*function)(id), id data, +of_thread_new(of_thread_t *thread, void (*function)(id), id object, const of_thread_attr_t *attr) { bool ret; pthread_attr_t pattr; if (pthread_attr_init(&pattr) != 0) return false; @try { + struct thread_ctx *ctx; + if (attr != NULL) { int policy, minPrio, maxPrio; struct sched_param param; if (attr->priority < 0 || attr->priority > 1) @@ -87,13 +107,19 @@ if (pthread_attr_setstacksize(&pattr, attr->stackSize) != 0) return false; } + + if ((ctx = malloc(sizeof(*ctx))) == NULL) + return false; + + ctx->function = function; + ctx->object = object; ret = (pthread_create(thread, &pattr, - (void*(*)(void*))function, (__bridge void*)data) == 0); + function_wrapper, ctx) == 0); } @finally { pthread_attr_destroy(&pattr); } return ret; Index: src/threading_winapi.m ================================================================== --- src/threading_winapi.m +++ src/threading_winapi.m @@ -24,11 +24,11 @@ return true; } bool -of_thread_new(of_thread_t *thread, id (*function)(id), id data, +of_thread_new(of_thread_t *thread, void (*function)(id), id object, const of_thread_attr_t *attr) { size_t stackSize = 0; int priority = 0; @@ -40,11 +40,11 @@ (THREAD_PRIORITY_HIGHEST - THREAD_PRIORITY_LOWEST); stackSize = attr->stackSize; } *thread = CreateThread(NULL, stackSize, - (LPTHREAD_START_ROUTINE)function, (__bridge void*)data, 0, NULL); + (LPTHREAD_START_ROUTINE)function, (__bridge void*)object, 0, NULL); if (thread == NULL) return false; if (priority > 0)