ObjFW  Check-in [0ede45ce93]

Overview
Comment:runtime: Free runtime created selectors at exit.

When a selector was created using sel_registerName(), it was not free'd
on exit, as selectors not created using sel_registerName did not need
any freeing. This adds a list of selectors created using
sel_registerName() and frees them on exit.

This is only relevant if objc_exit() is used to free all memory occupied
by the runtime. objc_exit() is only useful for debugging memory leaks,
so there was no real world effect.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 0ede45ce938faaa6dd5920fab7b63f17880065e947f24ece917c91b55dc666c6
User & Date: js on 2013-11-26 10:25:33
Other Links: manifest | tags
Context
2013-11-30
19:53
OFThread.m: Move #ifdefs. check-in: bd2389b6b8 user: js tags: trunk
2013-11-26
10:25
runtime: Free runtime created selectors at exit. check-in: 0ede45ce93 user: js tags: trunk
2013-11-24
19:21
OFZIPArchive: Fix a few type mismatches. check-in: f4da2cffa9 user: js tags: trunk
Changes

Modified src/runtime/selector.m from [64e4076187] to [743b892159].

28
29
30
31
32
33
34


35
36
37
38
39
40
41
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43







+
+







#else
# define SEL_MAX 0xFFFF
#endif

static struct objc_hashtable *selectors = NULL;
static uint32_t selectors_cnt = 0;
static struct objc_sparsearray *selector_names = NULL;
static void **free_list = NULL;
static size_t free_list_cnt = 0;

void
objc_register_selector(struct objc_abi_selector *sel)
{
	struct objc_selector *rsel;
	const char *name;

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85







86
87
88
89
90
91
92
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







-








+
+
+
+
+
+
+








	if (selectors != NULL &&
	    (rsel = objc_hashtable_get(selectors, name)) != NULL) {
		objc_global_mutex_unlock();
		return (SEL)rsel;
	}

	/* FIXME: Free on objc_exit() */
	if ((sel = malloc(sizeof(struct objc_abi_selector))) == NULL)
		OBJC_ERROR("Not enough memory to allocate selector!");

	if ((sel->name = strdup(name)) == NULL)
		OBJC_ERROR("Not enough memory to allocate selector!");

	sel->types = NULL;

	if ((free_list = realloc(free_list,
	    sizeof(void*) * (free_list_cnt + 2))) == NULL)
		OBJC_ERROR("Not enough memory to allocate selector!");

	free_list[free_list_cnt++] = sel;
	free_list[free_list_cnt++] = (char*)sel->name;

	objc_register_selector(sel);

	objc_global_mutex_unlock();
	return (SEL)sel;
}

void
120
121
122
123
124
125
126









127
128
129
130


131
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150







+
+
+
+
+
+
+
+
+




+
+

}

void
objc_free_all_selectors(void)
{
	objc_hashtable_free(selectors);
	objc_sparsearray_free(selector_names);

	if (free_list != NULL) {
		size_t i;

		for (i = 0; i < free_list_cnt; i++)
			free(free_list[i]);

		free(free_list);
	}

	selectors = NULL;
	selectors_cnt = 0;
	selector_names = NULL;
	free_list = NULL;
	free_list_cnt = 0;
}