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
}
|