ObjFW  Diff

Differences From Artifact [8ccdb1ee10]:

To Artifact [262fd1b7bb]:


1
2
3
4
5
6
7
8
9
/*
 * Copyright (c) 2008-2021 Jonathan Schleifer <js@nil.im>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *

|







1
2
3
4
5
6
7
8
9
/*
 * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#import "ObjFWRT.h"
#import "private.h"

#ifdef OF_HAVE_THREADS
# import "OFPlainMutex.h"
#endif

struct weakref {
	id **locations;
	size_t count;
};

static struct objc_hashtable *hashtable;
#ifdef OF_HAVE_THREADS
static OFSpinlock spinlock;







|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#import "ObjFWRT.h"
#import "private.h"

#ifdef OF_HAVE_THREADS
# import "OFPlainMutex.h"
#endif

struct WeakRef {
	id **locations;
	size_t count;
};

static struct objc_hashtable *hashtable;
#ifdef OF_HAVE_THREADS
static OFSpinlock spinlock;
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127

	return value;
}

id
objc_storeWeak(id *object, id value)
{
	struct weakref *old;

#ifdef OF_HAVE_THREADS
	if (OFSpinlockLock(&spinlock) != 0)
		OBJC_ERROR("Failed to lock spinlock!");
#endif

	if (*object != nil &&







|







113
114
115
116
117
118
119
120
121
122
123
124
125
126
127

	return value;
}

id
objc_storeWeak(id *object, id value)
{
	struct WeakRef *old;

#ifdef OF_HAVE_THREADS
	if (OFSpinlockLock(&spinlock) != 0)
		OBJC_ERROR("Failed to lock spinlock!");
#endif

	if (*object != nil &&
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
				break;
			}
		}
	}

	if (value != nil && class_respondsToSelector(object_getClass(value),
	    @selector(allowsWeakReference)) && [value allowsWeakReference]) {
		struct weakref *ref = objc_hashtable_get(hashtable, 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);







|







151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
				break;
			}
		}
	}

	if (value != nil && class_respondsToSelector(object_getClass(value),
	    @selector(allowsWeakReference)) && [value allowsWeakReference]) {
		struct WeakRef *ref = objc_hashtable_get(hashtable, 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);
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
	return value;
}

id
objc_loadWeakRetained(id *object)
{
	id value = nil;
	struct weakref *ref;

#ifdef OF_HAVE_THREADS
	if (OFSpinlockLock(&spinlock) != 0)
		OBJC_ERROR("Failed to lock spinlock!");
#endif

	if (*object != nil &&







|







184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
	return value;
}

id
objc_loadWeakRetained(id *object)
{
	id value = nil;
	struct WeakRef *ref;

#ifdef OF_HAVE_THREADS
	if (OFSpinlockLock(&spinlock) != 0)
		OBJC_ERROR("Failed to lock spinlock!");
#endif

	if (*object != nil &&
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
{
	objc_release(objc_initWeak(dest, objc_loadWeakRetained(src)));
}

void
objc_moveWeak(id *dest, id *src)
{
	struct weakref *ref;

#ifdef OF_HAVE_THREADS
	if (OFSpinlockLock(&spinlock) != 0)
		OBJC_ERROR("Failed to lock spinlock!");
#endif

	if (*src != nil &&







|







235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
{
	objc_release(objc_initWeak(dest, objc_loadWeakRetained(src)));
}

void
objc_moveWeak(id *dest, id *src)
{
	struct WeakRef *ref;

#ifdef OF_HAVE_THREADS
	if (OFSpinlockLock(&spinlock) != 0)
		OBJC_ERROR("Failed to lock spinlock!");
#endif

	if (*src != nil &&
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
#ifdef OF_HAVE_THREADS
	if (OFSpinlockUnlock(&spinlock) != 0)
		OBJC_ERROR("Failed to unlock spinlock!");
#endif
}

void
objc_zero_weak_references(id value)
{
	struct weakref *ref;

#ifdef OF_HAVE_THREADS
	if (OFSpinlockLock(&spinlock) != 0)
		OBJC_ERROR("Failed to lock spinlock!");
#endif

	if ((ref = objc_hashtable_get(hashtable, value)) != NULL) {







|

|







262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
#ifdef OF_HAVE_THREADS
	if (OFSpinlockUnlock(&spinlock) != 0)
		OBJC_ERROR("Failed to unlock spinlock!");
#endif
}

void
objc_zeroWeakReferences(id value)
{
	struct WeakRef *ref;

#ifdef OF_HAVE_THREADS
	if (OFSpinlockLock(&spinlock) != 0)
		OBJC_ERROR("Failed to lock spinlock!");
#endif

	if ((ref = objc_hashtable_get(hashtable, value)) != NULL) {