@@ -29,14 +29,13 @@ struct weak_ref { id **locations; size_t count; }; -static struct objc_hashtable *hashtable; -#ifdef OF_HAVE_THREADS -static of_spinlock_t spinlock; -#endif +#import "globals.h" +#define weak_refs objc_globals.weak_refs +#define weak_refs_lock objc_globals.weak_refs_lock static uint32_t obj_hash(const void *obj) { return (uint32_t)(uintptr_t)obj; @@ -48,14 +47,14 @@ return (obj1 == obj2); } OF_CONSTRUCTOR() { - hashtable = objc_hashtable_new(obj_hash, obj_equal, 2); + weak_refs = objc_hashtable_new(obj_hash, obj_equal, 2); #ifdef OF_HAVE_THREADS - if (!of_spinlock_new(&spinlock)) + if (!of_spinlock_new(&weak_refs_lock)) OBJC_ERROR("Failed to create spinlock!") #endif } id @@ -122,20 +121,20 @@ objc_storeWeak(id *object, id value) { struct weak_ref *old; #ifdef OF_HAVE_THREADS - if (!of_spinlock_lock(&spinlock)) + if (!of_spinlock_lock(&weak_refs_lock)) OBJC_ERROR("Failed to lock spinlock!") #endif if (*object != nil && - (old = objc_hashtable_get(hashtable, *object)) != NULL) { + (old = objc_hashtable_get(weak_refs, *object)) != NULL) { for (size_t i = 0; i < old->count; i++) { if (old->locations[i] == object) { if (--old->count == 0) { - objc_hashtable_delete(hashtable, + objc_hashtable_delete(weak_refs, *object); free(old->locations); free(old); } else { id **locations; @@ -157,18 +156,18 @@ } } if (value != nil && class_respondsToSelector(object_getClass(value), @selector(allowsWeakReference)) && [value allowsWeakReference]) { - struct weak_ref *ref = objc_hashtable_get(hashtable, value); + struct weak_ref *ref = objc_hashtable_get(weak_refs, value); if (ref == NULL) { if ((ref = calloc(1, sizeof(*ref))) == NULL) OBJC_ERROR("Not enough memory to allocate weak " "reference!"); - objc_hashtable_set(hashtable, value, ref); + objc_hashtable_set(weak_refs, value, ref); } if ((ref->locations = realloc(ref->locations, (ref->count + 1) * sizeof(id *))) == NULL) OBJC_ERROR("Not enough memory to allocate weak " @@ -179,11 +178,11 @@ value = nil; *object = value; #ifdef OF_HAVE_THREADS - if (!of_spinlock_unlock(&spinlock)) + if (!of_spinlock_unlock(&weak_refs_lock)) OBJC_ERROR("Failed to unlock spinlock!") #endif return value; } @@ -193,19 +192,19 @@ { id value = nil; struct weak_ref *ref; #ifdef OF_HAVE_THREADS - if (!of_spinlock_lock(&spinlock)) + if (!of_spinlock_lock(&weak_refs_lock)) OBJC_ERROR("Failed to lock spinlock!") #endif - if ((ref = objc_hashtable_get(hashtable, *object)) != NULL) + if ((ref = objc_hashtable_get(weak_refs, *object)) != NULL) value = *object; #ifdef OF_HAVE_THREADS - if (!of_spinlock_unlock(&spinlock)) + if (!of_spinlock_unlock(&weak_refs_lock)) OBJC_ERROR("Failed to unlock spinlock!") #endif if (class_respondsToSelector(object_getClass(value), @selector(retainWeakReference)) && [value retainWeakReference]) @@ -243,15 +242,15 @@ objc_moveWeak(id *dest, id *src) { struct weak_ref *ref; #ifdef OF_HAVE_THREADS - if (!of_spinlock_lock(&spinlock)) + if (!of_spinlock_lock(&weak_refs_lock)) OBJC_ERROR("Failed to lock spinlock!") #endif - if ((ref = objc_hashtable_get(hashtable, *src)) != NULL) { + if ((ref = objc_hashtable_get(weak_refs, *src)) != NULL) { for (size_t i = 0; i < ref->count; i++) { if (ref->locations[i] == src) { ref->locations[i] = dest; break; } @@ -260,11 +259,11 @@ *dest = *src; *src = nil; #ifdef OF_HAVE_THREADS - if (!of_spinlock_unlock(&spinlock)) + if (!of_spinlock_unlock(&weak_refs_lock)) OBJC_ERROR("Failed to unlock spinlock!") #endif } void @@ -271,23 +270,23 @@ objc_zero_weak_references(id value) { struct weak_ref *ref; #ifdef OF_HAVE_THREADS - if (!of_spinlock_lock(&spinlock)) + if (!of_spinlock_lock(&weak_refs_lock)) OBJC_ERROR("Failed to lock spinlock!") #endif - if ((ref = objc_hashtable_get(hashtable, value)) != NULL) { + if ((ref = objc_hashtable_get(weak_refs, value)) != NULL) { for (size_t i = 0; i < ref->count; i++) *ref->locations[i] = nil; - objc_hashtable_delete(hashtable, value); + objc_hashtable_delete(weak_refs, value); free(ref->locations); free(ref); } #ifdef OF_HAVE_THREADS - if (!of_spinlock_unlock(&spinlock)) + if (!of_spinlock_unlock(&weak_refs_lock)) OBJC_ERROR("Failed to unlock spinlock!") #endif }