Overview
Comment: | runtime: Fix associated objects |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
b0594b769ce2c4daa60a0cbeaa60d48f |
User & Date: | js on 2024-02-20 22:22:59 |
Other Links: | manifest | tags |
Context
2024-02-21
| ||
21:36 | Document ObjFWTest check-in: 3c55b7ac50 user: js tags: trunk | |
2024-02-20
| ||
22:22 | runtime: Fix associated objects check-in: b0594b769c user: js tags: trunk | |
22:07 | OFKernelEventObserverTests: Fix missing release check-in: 89b96428b9 user: js tags: trunk | |
Changes
Modified src/runtime/association.m from [b558229b1e] to [b59c5c9746].
︙ | ︙ | |||
14 15 16 17 18 19 20 | */ #include "config.h" #import "ObjFWRT.h" #import "private.h" | < < < < < < < < < < < < > > > > > > > | > > > > > > > | < < > < < < | > | | > | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | */ #include "config.h" #import "ObjFWRT.h" #import "private.h" struct Association { id object; objc_associationPolicy policy; }; #ifdef OF_HAVE_THREADS # define numSlots 8 /* needs to be a power of 2 */ # import "OFPlainMutex.h" static OFSpinlock spinlocks[numSlots]; #else # define numSlots 1 #endif static struct objc_hashtable *hashtables[numSlots]; static OF_INLINE size_t slotForObject(id object) { return ((size_t)((uintptr_t)object >> 4) & (numSlots - 1)); } static uint32_t hash(const void *object) { return (uint32_t)(uintptr_t)object; } static bool equal(const void *object1, const void *object2) { return (object1 == object2); } OF_CONSTRUCTOR() { for (size_t i = 0; i < numSlots; i++) { hashtables[i] = objc_hashtable_new(hash, equal, 2); #ifdef OF_HAVE_THREADS if (OFSpinlockNew(&spinlocks[i]) != 0) OBJC_ERROR("Failed to create spinlocks!"); #endif } } void objc_setAssociatedObject(id object, const void *key, id value, objc_associationPolicy policy) { size_t slot; switch (policy) { case OBJC_ASSOCIATION_ASSIGN: break; case OBJC_ASSOCIATION_RETAIN: case OBJC_ASSOCIATION_RETAIN_NONATOMIC: value = [value retain]; break; case OBJC_ASSOCIATION_COPY: case OBJC_ASSOCIATION_COPY_NONATOMIC: value = [value copy]; break; default: /* Don't know what to do, so do nothing. */ return; } slot = slotForObject(object); #ifdef OF_HAVE_THREADS if (OFSpinlockLock(&spinlocks[slot]) != 0) OBJC_ERROR("Failed to lock spinlock!"); @try { #endif struct objc_hashtable *objectHashtable; struct Association *association; objectHashtable = objc_hashtable_get(hashtables[slot], object); if (objectHashtable == NULL) { objectHashtable = objc_hashtable_new(hash, equal, 2); objc_hashtable_set(hashtables[slot], object, objectHashtable); } association = objc_hashtable_get(objectHashtable, key); if (association != NULL) { switch (association->policy) { case OBJC_ASSOCIATION_RETAIN: case OBJC_ASSOCIATION_RETAIN_NONATOMIC: |
︙ | ︙ | |||
130 131 132 133 134 135 136 | } #endif } id objc_getAssociatedObject(id object, const void *key) { | < | > | | 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | } #endif } id objc_getAssociatedObject(id object, const void *key) { size_t slot = slotForObject(object); #ifdef OF_HAVE_THREADS if (OFSpinlockLock(&spinlocks[slot]) != 0) OBJC_ERROR("Failed to lock spinlock!"); @try { #endif struct objc_hashtable *objectHashtable; struct Association *association; objectHashtable = objc_hashtable_get(hashtables[slot], object); if (objectHashtable == NULL) return nil; association = objc_hashtable_get(objectHashtable, key); if (association == NULL) return nil; |
︙ | ︙ | |||
167 168 169 170 171 172 173 | } #endif } void objc_removeAssociatedObjects(id object) { | < | > | | 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | } #endif } void objc_removeAssociatedObjects(id object) { size_t slot = slotForObject(object); #ifdef OF_HAVE_THREADS if (OFSpinlockLock(&spinlocks[slot]) != 0) OBJC_ERROR("Failed to lock spinlock!"); @try { #endif struct objc_hashtable *objectHashtable; objectHashtable = objc_hashtable_get(hashtables[slot], object); if (objectHashtable == NULL) return; for (uint32_t i = 0; i < objectHashtable->size; i++) { struct Association *association; if (objectHashtable->data[i] == NULL || |
︙ | ︙ | |||
205 206 207 208 209 210 211 | default: break; } free(association); } | | > | 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | default: break; } free(association); } objc_hashtable_delete(hashtables[slot], object); objc_hashtable_free(objectHashtable); #ifdef OF_HAVE_THREADS } @finally { if (OFSpinlockUnlock(&spinlocks[slot]) != 0) OBJC_ERROR("Failed to unlock spinlock!"); } #endif } |