ObjFW  Diff

Differences From Artifact [64e4076187]:

To Artifact [743b892159]:

  • File src/runtime/selector.m — part of check-in [0ede45ce93] at 2013-11-26 10:25:33 on branch trunk — 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. (user: js, size: 3298) [annotate] [blame] [check-ins using]


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