diff --git a/Source/GSPrivate.h b/Source/GSPrivate.h index 1e04fc0..6aed596 100644 --- a/Source/GSPrivate.h +++ b/Source/GSPrivate.h @@ -543,6 +543,20 @@ GSPrivateIsCollectable(const void *ptr) GS_ATTRIB_PRIVATE; NSZone* GSAtomicMallocZone (void); +#if GS_USE_LIBDISPATCH +void +GSPrivateDispatchInitialize(void) GS_ATTRIB_PRIVATE; + +/* These functions are used by libdispatch to initialize + * NSAutoreleasePool for its worker threads. + */ +void* +GSPrivateAutoreleasePoolAllocate(void) GS_ATTRIB_PRIVATE; +void +GSPrivateAutoreleasePoolDeallocate(void* param) GS_ATTRIB_PRIVATE; +#endif /* GS_USE_LIBDISPATCH */ + + /* Implementation of ShellSort for GNUStep */ #if GS_USE_SHELLSORT diff --git a/Source/NSAutoreleasePool.m b/Source/NSAutoreleasePool.m index 2230e4a..4e9a6b0 100644 --- a/Source/NSAutoreleasePool.m +++ b/Source/NSAutoreleasePool.m @@ -823,3 +823,29 @@ pop_pool_from_cache (struct autorelease_thread_vars *tv) @end #endif // !GS_WITH_GC + +# if GS_USE_LIBDISPATCH +void* +GSPrivateAutoreleasePoolAllocate(void) +{ +#ifdef ARC_RUNTIME + return NULL; +#else + return [NSAutoreleasePool new]; +#endif +} + +#ifdef ARC_RUNTIME +#define ARC_UNUSED __attribute__((unused)) +#else +#define ARC_UNUSED +#endif +void +GSPrivateAutoreleasePoolDeallocate(void* param ARC_UNUSED) +{ +#ifndef ARC_RUNTIME + NSAutoreleasePool *pool = param; + [pool drain]; +#endif +} +# endif /* GS_USE_LIBDISPATCH */ diff --git a/Source/NSObject.m b/Source/NSObject.m index 75fb009..1e9d238 100644 --- a/Source/NSObject.m +++ b/Source/NSObject.m @@ -1147,6 +1147,10 @@ static id gs_weak_load(id obj) */ zombieClass = objc_lookUpClass("NSZombie"); +#if GS_USE_LIBDISPATCH + GSPrivateDispatchInitialize(); +#endif + /* Now that we have a workign autorelease system and working string * classes we are able to set up notifications. */ diff --git a/Source/externs.m b/Source/externs.m index a0e4b90..24e40cf 100644 --- a/Source/externs.m +++ b/Source/externs.m @@ -30,6 +30,10 @@ #import "GSPrivate.h" +#if GS_USE_LIBDISPATCH +#import +#endif + /* PENDING some string constants are scattered about in the class impl files and should be moved here @@ -299,6 +303,29 @@ GSPrivateBuildStrings() } } +#if GS_USE_LIBDISPATCH +void +GSPrivateDispatchInitialize(void) +{ + void** _dispatch_begin_NSAutoReleasePool = dlsym(RTLD_DEFAULT, "_dispatch_begin_NSAutoReleasePool"); + if (NULL != _dispatch_begin_NSAutoReleasePool) + { + void** _dispatch_end_NSAutoReleasePool = dlsym(RTLD_DEFAULT, "_dispatch_end_NSAutoReleasePool"); + if (NULL != _dispatch_end_NSAutoReleasePool) + { + *_dispatch_begin_NSAutoReleasePool = (void*)GSPrivateAutoreleasePoolAllocate; + *_dispatch_end_NSAutoReleasePool = (void*)GSPrivateAutoreleasePoolDeallocate; + } + } +#if GS_WITH_GC || __OBJC_GC__ + void** dispatch_begin_thread_4GC = dlsym(RTLD_DEFAULT, "dispatch_begin_thread_4GC"); + if (NULL != dispatch_begin_thread_4GC) + { + *dispatch_begin_thread_4GC = (void*)GSRegisterThreadWithGC; + } +#endif +} +#endif /* For bug in gcc 3.1. See NSByteOrder.h */