summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2009-10-19 00:49:29 +0000
committerTavian Barnes <tavianator@gmail.com>2009-10-19 00:49:29 +0000
commit95895823f75108cbfed2697498e4e097f493b236 (patch)
tree77efe89b445f168b7d0c63f3fd5f0a23f6e743e8
parent8710689500d3d35d04aabd727f12698590a816cb (diff)
downloaddimension-95895823f75108cbfed2697498e4e097f493b236.tar.xz
Fix some memory leaks.
dmnsn_delete_pigment() was not using the free_fn, and kD splay trees were not being deleted after raytracing finished.
-rw-r--r--libdimension/kD_splay_tree.c26
-rw-r--r--libdimension/pigments.c1
-rw-r--r--libdimension/raytrace.c8
-rw-r--r--libdimension/texture.c9
4 files changed, 30 insertions, 14 deletions
diff --git a/libdimension/kD_splay_tree.c b/libdimension/kD_splay_tree.c
index de70edf..a661602 100644
--- a/libdimension/kD_splay_tree.c
+++ b/libdimension/kD_splay_tree.c
@@ -29,10 +29,11 @@ dmnsn_kD_splay_tree *
dmnsn_new_kD_splay_tree()
{
dmnsn_kD_splay_tree *tree = malloc(sizeof(dmnsn_kD_splay_tree));
- if (!tree) {
+ if (tree) {
+ tree->root = NULL;
+ } else {
dmnsn_error(DMNSN_SEVERITY_HIGH, "kD splay tree allocation failed.");
}
- tree->root = NULL;
return tree;
}
@@ -67,20 +68,25 @@ dmnsn_kD_splay_copy(dmnsn_kD_splay_tree *tree)
/* Recursively free a kD splay tree */
void
-dmnsn_delete_kD_splay_tree(dmnsn_kD_splay_tree *tree)
+dmnsn_delete_kD_splay_tree_recursive(dmnsn_kD_splay_node *node)
{
- dmnsn_kD_splay_node *node = tree->root;
if (node) {
- tree->root = node->contains;
- dmnsn_delete_kD_splay_tree(tree);
-
- tree->root = node->container;
- dmnsn_delete_kD_splay_tree(tree);
-
+ dmnsn_delete_kD_splay_tree_recursive(node->contains);
+ dmnsn_delete_kD_splay_tree_recursive(node->container);
dmnsn_delete_kD_splay_node(node);
}
}
+/* Free a kD splay tree */
+void
+dmnsn_delete_kD_splay_tree(dmnsn_kD_splay_tree *tree)
+{
+ if (tree) {
+ dmnsn_delete_kD_splay_tree_recursive(tree->root);
+ free(tree);
+ }
+}
+
/* Return whether node1 contains node2 */
static int dmnsn_box_contains(dmnsn_vector p,
dmnsn_vector min, dmnsn_vector max);
diff --git a/libdimension/pigments.c b/libdimension/pigments.c
index 22f75e8..adf44c4 100644
--- a/libdimension/pigments.c
+++ b/libdimension/pigments.c
@@ -40,6 +40,7 @@ dmnsn_new_solid_pigment(dmnsn_color color)
*solid = color;
pigment->pigment_fn = &dmnsn_solid_pigment_fn;
+ pigment->free_fn = &free;
pigment->ptr = solid;
}
diff --git a/libdimension/raytrace.c b/libdimension/raytrace.c
index 3e67c4b..bb88940 100644
--- a/libdimension/raytrace.c
+++ b/libdimension/raytrace.c
@@ -140,7 +140,7 @@ dmnsn_raytrace_scene_multithread(dmnsn_raytrace_payload *payload)
payloads[i].threads = nthreads;
if (i > 0) {
payloads[i].kD_splay_tree =
- dmnsn_kD_splay_copy(payloads[i].kD_splay_tree);
+ dmnsn_kD_splay_copy(payloads[0].kD_splay_tree);
}
if (pthread_create(&threads[i], NULL,
@@ -148,11 +148,14 @@ dmnsn_raytrace_scene_multithread(dmnsn_raytrace_payload *payload)
&payloads[i]) != 0)
{
for (j = 0; j < i; ++j) {
- if (pthread_join(threads[i], &ptr)) {
+ if (pthread_join(threads[j], &ptr)) {
dmnsn_error(DMNSN_SEVERITY_MEDIUM,
"Couldn't join worker thread in failed raytrace engine"
" initialization.");
} else {
+ /* Only free on a successful join - otherwise we might free a pointer
+ out from under a running thread */
+ dmnsn_delete_kD_splay_tree(payloads[j].kD_splay_tree);
free(ptr);
}
}
@@ -170,6 +173,7 @@ dmnsn_raytrace_scene_multithread(dmnsn_raytrace_payload *payload)
if (retval == 0) {
retval = *(int *)ptr;
}
+ dmnsn_delete_kD_splay_tree(payloads[i].kD_splay_tree);
free(ptr);
}
}
diff --git a/libdimension/texture.c b/libdimension/texture.c
index a5ebd90..3867628 100644
--- a/libdimension/texture.c
+++ b/libdimension/texture.c
@@ -32,11 +32,16 @@ dmnsn_new_pigment()
return pigment;
}
-/* Free a dummy pigment */
+/* Free a pigment */
void
dmnsn_delete_pigment(dmnsn_pigment *pigment)
{
- free(pigment);
+ if (pigment) {
+ if (pigment->free_fn) {
+ (*pigment->free_fn)(pigment->ptr);
+ }
+ free(pigment);
+ }
}
/* Allocate a dummy texture */