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
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))
		return;

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

	if (cls->superclass != Nil)
		objc_sparsearray_copy(cls->dtable, cls->superclass->dtable);







|







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_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
{
	if (cls->info & OBJC_CLASS_INFO_INITIALIZED)
		return;

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







	/*
	 * 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)







>
>
>
>
>
>







<
<
<







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;




	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
}

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)
		objc_sparsearray_free(rcls->dtable);

	rcls->dtable = NULL;

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







<
<
<





|







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->subclass_list != NULL) {
		free(rcls->subclass_list);
		rcls->subclass_list = 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

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_INITIALIZED = 0x400
};

struct objc_object {
	Class isa;
};

struct objc_selector {







>
|







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 = 0x800
};

struct objc_object {
	Class isa;
};

struct objc_selector {