Browse Source

[settings] Avoid memory leak when unregistering autovivified settings blocks

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 13 years ago
parent
commit
071b4000d9
1 changed files with 27 additions and 3 deletions
  1. 27
    3
      src/core/settings.c

+ 27
- 3
src/core/settings.c View File

230
 /** Root settings block */
230
 /** Root settings block */
231
 #define settings_root generic_settings_root.settings
231
 #define settings_root generic_settings_root.settings
232
 
232
 
233
+/** Autovivified settings block */
234
+struct autovivified_settings {
235
+	/** Reference count */
236
+	struct refcnt refcnt;
237
+	/** Generic settings block */
238
+	struct generic_settings generic;
239
+};
240
+
241
+/**
242
+ * Free autovivified settings block
243
+ *
244
+ * @v refcnt		Reference count
245
+ */
246
+static void autovivified_settings_free ( struct refcnt *refcnt ) {
247
+	struct autovivified_settings *autovivified =
248
+		container_of ( refcnt, struct autovivified_settings, refcnt );
249
+
250
+	generic_settings_clear ( &autovivified->generic.settings );
251
+	free ( autovivified );
252
+}
253
+
233
 /**
254
 /**
234
  * Find child named settings block
255
  * Find child named settings block
235
  *
256
  *
264
 static struct settings * autovivify_child_settings ( struct settings *parent,
285
 static struct settings * autovivify_child_settings ( struct settings *parent,
265
 						     const char *name ) {
286
 						     const char *name ) {
266
 	struct {
287
 	struct {
267
-		struct generic_settings generic;
288
+		struct autovivified_settings autovivified;
268
 		char name[ strlen ( name ) + 1 /* NUL */ ];
289
 		char name[ strlen ( name ) + 1 /* NUL */ ];
269
 	} *new_child;
290
 	} *new_child;
270
 	struct settings *settings;
291
 	struct settings *settings;
281
 		return NULL;
302
 		return NULL;
282
 	}
303
 	}
283
 	memcpy ( new_child->name, name, sizeof ( new_child->name ) );
304
 	memcpy ( new_child->name, name, sizeof ( new_child->name ) );
284
-	generic_settings_init ( &new_child->generic, NULL );
285
-	settings = &new_child->generic.settings;
305
+	ref_init ( &new_child->autovivified.refcnt,
306
+		   autovivified_settings_free );
307
+	generic_settings_init ( &new_child->autovivified.generic,
308
+				&new_child->autovivified.refcnt );
309
+	settings = &new_child->autovivified.generic.settings;
286
 	register_settings ( settings, parent, new_child->name );
310
 	register_settings ( settings, parent, new_child->name );
287
 	return settings;
311
 	return settings;
288
 }
312
 }

Loading…
Cancel
Save