When linking libdispatch, register to create / destroy autorelease pools at the

correct time.  This fixes the intermittent problems when using libdispatch from
LanguageKit, among other things.
This commit is contained in:
theraven 2013-04-15 15:46:39 +00:00
parent ed84a2b0a2
commit 8d954d1cb8
3 changed files with 28 additions and 0 deletions

View File

@ -21,6 +21,10 @@ Objective-C programs. Highlights of this release include:
- Significant improvements in property introspection and an exhaustive test
suite.
- Improved integration with libdispatch. The runtime will correctly register
work queues with the garbage collector or create autorelease pools around
block invocations.
- A new exception implementation providing better integration with foreign
exceptions (e.g. C++ exceptions). The new ABI is supported by clang 3.3 when
compiling with -fobjc-runtime=gnustep-1.7 (or higher). The old ABI is still

View File

@ -21,6 +21,10 @@ static void *alloc(size_t size)
return calloc(size, 1);
}
void objc_registerThreadWithCollector(void) {}
void objc_unregisterThreadWithCollector(void) {}
void objc_assertRegisteredThreadWithCollector() {}
PRIVATE struct gc_ops gc_ops_none =
{
.allocate_class = allocate_class,

View File

@ -1,6 +1,8 @@
#include <stdlib.h>
#include <assert.h>
#include "objc/runtime.h"
#include "objc/objc-auto.h"
#include "objc/objc-arc.h"
#include "lock.h"
#include "loader.h"
#include "visibility.h"
@ -35,6 +37,12 @@ static void log_memory_stats(void)
/* Number of threads that are alive. */
int __objc_runtime_threads_alive = 1; /* !T:MUTEX */
// libdispatch hooks for registering threads
__attribute__((weak)) void (*dispatch_begin_thread_4GC)(void);
__attribute__((weak)) void (*dispatch_end_thread_4GC)(void);
__attribute__((weak)) void *(*_dispatch_begin_NSAutoReleasePool)(void);
__attribute__((weak)) void (*_dispatch_end_NSAutoReleasePool)(void *);
void __objc_exec_class(struct objc_module_abi_8 *module)
{
static BOOL first_run = YES;
@ -73,6 +81,18 @@ void __objc_exec_class(struct objc_module_abi_8 *module)
{
atexit(log_memory_stats);
}
if (dispatch_begin_thread_4GC != 0) {
dispatch_begin_thread_4GC = objc_registerThreadWithCollector;
}
if (dispatch_end_thread_4GC != 0) {
dispatch_end_thread_4GC = objc_unregisterThreadWithCollector;
}
if (_dispatch_begin_NSAutoReleasePool != 0) {
_dispatch_begin_NSAutoReleasePool = objc_autoreleasePoolPush;
}
if (_dispatch_end_NSAutoReleasePool != 0) {
_dispatch_end_NSAutoReleasePool = objc_autoreleasePoolPop;
}
}
// The runtime mutex is held for the entire duration of a load. It does