ObjFW  Check-in [8f02ff02dc]

Overview
Comment:Fix a possible race condition in initialize_class.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 8f02ff02dca421fbdbcd20c63823660b087c77805c57f0f5187b41b16401383c
User & Date: js on 2012-08-05 16:52:14
Other Links: manifest | tags
Context
2012-08-05
17:22
Use recursive pthread mutexes if available. check-in: 1e10b33066 user: js tags: trunk
16:52
Fix a possible race condition in initialize_class. check-in: 8f02ff02dc user: js tags: trunk
12:17
Use -Wno-objc-root-class if available. check-in: 0c87d8f53b user: js tags: trunk
Changes

Modified src/runtime/class.m from [0f8bf1f4e6] to [cde4d41e21].

133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
133
134
135
136
137
138
139

140
141
142
143
144
145
146
147







-
+







void
objc_update_dtable(Class cls)
{
	struct objc_method_list *ml;
	struct objc_category **cats;
	unsigned int i;

	if (!(cls->info & OBJC_CLASS_INFO_INITIALIZED))
	if (!(cls->info & OBJC_CLASS_INFO_DTABLE))
		return;

	if (cls->dtable == empty_dtable)
		cls->dtable = objc_sparsearray_new();

	if (cls->superclass != Nil)
		objc_sparsearray_copy(cls->dtable, cls->superclass->dtable);
238
239
240
241
242
243
244






245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257



258
259
260
261
262
263
264







+
+
+
+
+
+







-
-
-







{
	if (cls->info & OBJC_CLASS_INFO_INITIALIZED)
		return;

	if (cls->superclass)
		initialize_class(cls->superclass);

	cls->info |= OBJC_CLASS_INFO_DTABLE;
	cls->isa->info |= OBJC_CLASS_INFO_DTABLE;

	objc_update_dtable(cls);
	objc_update_dtable(cls->isa);

	/*
	 * Set it first to prevent calling it recursively due to message sends
	 * in the initialize method
	 */
	cls->info |= OBJC_CLASS_INFO_INITIALIZED;
	cls->isa->info |= OBJC_CLASS_INFO_INITIALIZED;

	objc_update_dtable(cls);
	objc_update_dtable(cls->isa);

	call_method(cls, "initialize");
}

void
objc_initialize_class(Class cls)
{
	if (cls->info & OBJC_CLASS_INFO_INITIALIZED)
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547

548
549
550
551
552
553
554
535
536
537
538
539
540
541



542
543
544
545
546

547
548
549
550
551
552
553
554







-
-
-





-
+







}

static void
free_class(Class rcls)
{
	struct objc_abi_class *cls = (struct objc_abi_class*)rcls;

	if (!(rcls->info & OBJC_CLASS_INFO_INITIALIZED))
		return;

	if (rcls->subclass_list != NULL) {
		free(rcls->subclass_list);
		rcls->subclass_list = NULL;
	}

	if (rcls->dtable != NULL)
	if (rcls->dtable != NULL && rcls->dtable != empty_dtable)
		objc_sparsearray_free(rcls->dtable);

	rcls->dtable = NULL;

	if (rcls->superclass != Nil)
		cls->superclass = rcls->superclass->name;
}

Modified src/runtime/runtime.h from [1dc0fb3f7f] to [03d74b30fd].

55
56
57
58
59
60
61

62

63
64
65
66
67
68
69
55
56
57
58
59
60
61
62

63
64
65
66
67
68
69
70







+
-
+








enum objc_abi_class_info {
	OBJC_CLASS_INFO_CLASS	    = 0x001,
	OBJC_CLASS_INFO_METACLASS   = 0x002,
	OBJC_CLASS_INFO_NEW_ABI	    = 0x010,
	OBJC_CLASS_INFO_SETUP	    = 0x100,
	OBJC_CLASS_INFO_LOADED	    = 0x200,
	OBJC_CLASS_INFO_DTABLE	    = 0x400,
	OBJC_CLASS_INFO_INITIALIZED = 0x400
	OBJC_CLASS_INFO_INITIALIZED = 0x800
};

struct objc_object {
	Class isa;
};

struct objc_selector {