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
#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;



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








>
>







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

	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;








	objc_register_selector(sel);

	objc_global_mutex_unlock();
	return (SEL)sel;
}

void







<








>
>
>
>
>
>
>







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


	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
}

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










	selectors = NULL;
	selectors_cnt = 0;
	selector_names = NULL;


}







>
>
>
>
>
>
>
>
>




>
>

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