Permalink
Browse files

Added support for GNUstep

  • Loading branch information...
beelsebob committed Jun 18, 2012
1 parent 37466bc commit 1c0b22ca08b409bfeb83d6cb3d1030985847daa2
Showing with 83 additions and 1 deletion.
  1. +31 −0 GNUmakefile
  2. +52 −1 Source/MAZeroingWeakRef.m
View
@@ -0,0 +1,31 @@
+include $(GNUSTEP_MAKEFILES)/common.make
+
+CC=clang
+
+LIBRARY_NAME = libweakref
+libweakref_HEADER_FILES_DIR = Source
+libweakref_HEADER_FILES = \
+ MAZeroingWeakRef.h \
+ MAWeakArray.h \
+ MAWeakDictionary.h \
+ MAZeroingWeakProxy.h \
+ MANotificationCenterAdditions.h \
+ MAZeroingWeakRefNativeZWRNotAllowedTable.h
+libweakref_HEADER_FILES_INSTALL_DIR = MAZeroingWeakRef
+
+libweakref_OBJC_FILES = \
+ Source/MANotificationCenterAdditions.m \
+ Source/MAWeakArray.m \
+ Source/MAWeakDictionary.m \
+ Source/MAZeroingWeakProxy.m \
+ Source/MAZeroingWeakRef.m
+
+libweakref_RESOURCE_FILES =
+libweakref_CFLAGS = -fblocks -fobjc-nonfragile-abi -g -Os
+libweakref_OBJCFLAGS = -fblocks -fobjc-nonfragile-abi -g -Os
+libweakref_OBJC_LIBS = -ldispatch -lcrypto
+libweakref_LDFLAGS = -g -Os
+libweakref_INCLUDE_DIRS = -ISource/ -I/usr/local/ssl/include
+
+include $(GNUSTEP_MAKEFILES)/library.make
+
View
@@ -9,6 +9,7 @@
#import "MAZeroingWeakRefNativeZWRNotAllowedTable.h"
+#if __APPLE__
#import <CommonCrypto/CommonDigest.h>
#import <dlfcn.h>
@@ -17,6 +18,10 @@
#import <mach/mach.h>
#import <mach/port.h>
#import <pthread.h>
+#else
+#import <pthread.h>
+#include <openssl/sha.h>
+#endif
/*
@@ -154,7 +159,11 @@ @implementation MAZeroingWeakRef
static pthread_mutex_t gMutex;
+#if __APPLE__
static CFMutableDictionaryRef gObjectWeakRefsMap; // maps (non-retained) objects to CFMutableSetRefs containing weak refs
+#else
+static NSMapTable *gObjectWeakRefsMap;
+#endif
static NSMutableSet *gCustomSubclasses;
static NSMutableDictionary *gCustomSubclassMap; // maps regular classes to their custom subclasses
@@ -174,14 +183,19 @@ + (void)initialize
pthread_mutex_init(&gMutex, &mutexattr);
pthread_mutexattr_destroy(&mutexattr);
+#if __APPLE__
gObjectWeakRefsMap = CFDictionaryCreateMutable(NULL, 0, NULL, &kCFTypeDictionaryValueCallBacks);
+#else
+ gObjectWeakRefsMap = [[NSMapTable mapTableWithWeakToStrongObjects] retain];
+#endif
gCustomSubclasses = [[NSMutableSet alloc] init];
gCustomSubclassMap = [[NSMutableDictionary alloc] init];
// see if the 10.7 ZWR runtime functions are available
// nothing special about objc_allocateClassPair, it just
// seems like a reasonable and safe choice for finding
// the runtime functions
+#if __APPLE__
Dl_info info;
int success = dladdr(objc_allocateClassPair, &info);
if(success)
@@ -203,6 +217,7 @@ + (void)initialize
}
}
}
+#endif
#if COREFOUNDATION_HACK_LEVEL >= 3
gCFWeakTargets = CFSetCreateMutable(NULL, 0, NULL);
@@ -231,6 +246,7 @@ static void WhileLocked(void (^block)(void))
static void AddWeakRefToObject(id obj, MAZeroingWeakRef *ref)
{
+#if __APPLE__
CFMutableSetRef set = (void *)CFDictionaryGetValue(gObjectWeakRefsMap, obj);
if(!set)
{
@@ -239,16 +255,32 @@ static void AddWeakRefToObject(id obj, MAZeroingWeakRef *ref)
CFRelease(set);
}
CFSetAddValue(set, ref);
+#else
+ NSMutableSet *set = [gObjectWeakRefsMap objectForKey:obj];
+ if (!set)
+ {
+ set = [[NSMutableSet alloc] init];
+ [gObjectWeakRefsMap setObject:set forKey:obj];
+ [set release];
+ }
+ [set addObject:ref];
@mikeash

mikeash Jun 18, 2012

The use of NSMutableSet will retain weak references to an object even after their main user is done with them, potentially leading to unbounded memory use. Use NSHashTable instead?

+#endif
}
static void RemoveWeakRefFromObject(id obj, MAZeroingWeakRef *ref)
{
+#if __APPLE__
CFMutableSetRef set = (void *)CFDictionaryGetValue(gObjectWeakRefsMap, obj);
CFSetRemoveValue(set, ref);
+#else
+ NSMutableSet *set = [gObjectWeakRefsMap objectForKey:obj];
+ [set removeObject:ref];
+#endif
}
static void ClearWeakRefsForObject(id obj)
{
+#if __APPLE__
CFMutableSetRef set = (void *)CFDictionaryGetValue(gObjectWeakRefsMap, obj);
if(set)
{
@@ -258,6 +290,17 @@ static void ClearWeakRefsForObject(id obj)
[setCopy release];
CFDictionaryRemoveValue(gObjectWeakRefsMap, obj);
}
+#else
+ NSMutableSet *set = [gObjectWeakRefsMap objectForKey:obj];
+ if (set)
+ {
+ NSSet *setCopy = [[NSSet alloc] initWithSet:set];
+ [setCopy makeObjectsPerformSelector:@selector(_zeroTarget)];
+ [setCopy makeObjectsPerformSelector:@selector(_executeCleanupBlockWithTarget:) withObject:obj];
+ [setCopy release];
+ [gObjectWeakRefsMap removeObjectForKey:obj];
+ }
+#endif
}
static Class GetCustomSubclass(id obj)
@@ -541,15 +584,23 @@ static BOOL HashPresentInTable(unsigned char *hash, int length, struct _NativeZW
return NO;
}
+#if !__APPLE__
+#define CC_SHA1_DIGEST_LENGTH 20
+#endif
+
static BOOL CanNativeZWRClass(Class c)
@mikeash

mikeash Jun 18, 2012

Is it necessary to make all the crazy SHA1 stuff work in GNUStep? I'm guessing GNUStep either doesn't support __weak at all, or it supports it on every class. In either case, this function could be short-circuited to return YES on GNUStep without any of the crazy shenanigans needed on OS X.

{
if(!c)
return YES;
const char *name = class_getName(c);
unsigned char hash[CC_SHA1_DIGEST_LENGTH];
+#if __APPLE__
CC_SHA1(name, strlen(name), hash);
-
+#else
+ SHA1((const unsigned char *)name, strlen(name), hash);
+#endif
+
if(HashPresentInTable(hash, CC_SHA1_DIGEST_LENGTH, _MAZeroingWeakRefClassNativeWeakReferenceNotAllowedTable))
return NO;
else

0 comments on commit 1c0b22c

Please sign in to comment.