From 3d451321887f6907a3b0d9cda82f9f013617488f Mon Sep 17 00:00:00 2001 From: rfm Date: Mon, 30 Apr 2007 05:27:47 +0000 Subject: [PATCH] Add better forwarding code and fix for thread memory leak git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/libobjc/trunk@25099 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 6 ++++++ objc/objc-api.h | 7 +++++-- sendmsg.c | 20 ++++++++++++++++---- thr-pthreads.c | 32 ++++++++++++++++++++++++++------ 4 files changed, 53 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 71c4f3c..eb0b299 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2007-04-30 Richard Frith-Macdonald + + * sendmsg.c: Add forward2 + * objc/objc-api.h: Add forward2 + * thr-pthreads.c: Fix memory leak + 2006-02-24 Jeremy Bettis * misc.c: Added some missing objc_DECLARE keywords on function pointer definitions. diff --git a/objc/objc-api.h b/objc/objc-api.h index e0e49e2..36d5834 100644 --- a/objc/objc-api.h +++ b/objc/objc-api.h @@ -431,11 +431,14 @@ objc_EXPORT void *(*_objc_calloc)(size_t, size_t); objc_EXPORT void (*_objc_free)(void *); /* -** Hook for method forwarding. This makes it easy to substitute a +** Hooks for method forwarding. This makes it easy to substitute a ** library, such as ffcall, that implements closures, thereby avoiding -** gcc's __builtin_apply problems. +** gcc's __builtin_apply problems. __objc_msg_forward2's result will +** be preferred over that of __objc_msg_forward if both are set and +** return non-NULL. */ objc_EXPORT IMP (*__objc_msg_forward)(SEL); +objc_EXPORT IMP (*__objc_msg_forward2)(id, SEL); Method_t class_get_class_method(MetaClass _class, SEL aSel); diff --git a/sendmsg.c b/sendmsg.c index 6e0e436..428ac00 100644 --- a/sendmsg.c +++ b/sendmsg.c @@ -52,10 +52,15 @@ Boston, MA 02110-1301, USA. */ /* The uninstalled dispatch table */ struct sarray *__objc_uninstalled_dtable = 0; /* !T:MUTEX */ -/* Hook for method forwarding. If it is set, is invoked to return a - function that performs the real forwarding. Otherwise the libgcc - based functions (__builtin_apply and friends) are used. */ +/* Two hooks for method forwarding. If either is set, it is invoked + * to return a function that performs the real forwarding. If both + * are set, the result of __objc_msg_forward2 will be preferred over + * that of __objc_msg_forward. If both return NULL or are unset, + * the libgcc based functions (__builtin_apply and friends) are + * used. + */ IMP (*__objc_msg_forward) (SEL) = NULL; +IMP (*__objc_msg_forward2) (id, SEL) = NULL; /* Send +initialize to class */ static void __objc_send_initialize (Class); @@ -90,7 +95,14 @@ IMP __objc_get_forward_imp (SEL sel) { /* If a custom forwarding hook was registered, try getting a forwarding - * function from it. */ + function from it. There are two forward routine hooks, one that + takes the receiver as an argument and one that does not. */ + if (__objc_msg_forward2) + { + IMP result; + if ((result = __objc_msg_forward2 (rcv, sel)) != NULL) + return result; + } if (__objc_msg_forward) { IMP result; diff --git a/thr-pthreads.c b/thr-pthreads.c index d73db47..1657261 100644 --- a/thr-pthreads.c +++ b/thr-pthreads.c @@ -31,6 +31,8 @@ Boston, MA 02110-1301, USA. */ /* Key structure for maintaining thread specific storage */ static pthread_key_t _objc_thread_storage; +static pthread_attr_t _objc_thread_attribs; + /* Backend initialization functions */ @@ -39,17 +41,34 @@ int __objc_init_thread_system(void) { /* Initialize the thread storage key */ - return pthread_key_create(&_objc_thread_storage, NULL); + if (pthread_key_create(&_objc_thread_storage, NULL) == 0) + { + /* + * The normal default detach state for threads is PTHREAD_CREATE_JOINABLE + * which causes threads to not die when you think they should. + */ + if (pthread_attr_init(&_objc_thread_attribs) == 0) + { + if (pthread_attr_setdetachstate(&_objc_thread_attribs, + PTHREAD_CREATE_DETACHED) == 0) + return 0; + } + } + + return -1; } /* Close the threads subsystem. */ int __objc_close_thread_system(void) { - /* Destroy the thread storage key */ - /* Not implemented yet */ - /* return pthread_key_delete(&_objc_thread_storage); */ - return 0; + if (pthread_key_delete(_objc_thread_storage) == 0) + { + if (pthread_attr_destroy(&_objc_thread_attribs) == 0) + return 0; + } + + return -1; } /* Backend thread functions */ @@ -61,7 +80,8 @@ __objc_thread_detach(void (*func)(void *arg), void *arg) objc_thread_t thread_id; pthread_t new_thread_handle; - if ( !(pthread_create(&new_thread_handle, NULL, (void *)func, arg)) ) + if ( !(pthread_create(&new_thread_handle, &_objc_thread_attribs, + (void *)func, arg)) ) thread_id = *(objc_thread_t *)&new_thread_handle; else thread_id = NULL;