summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2009-10-26 00:25:21 -0400
committerTavian Barnes <tavianator@gmail.com>2009-10-26 00:25:21 -0400
commitc6612fb215d71ac2bea3b614786cf585cd1a6c74 (patch)
treefa8a4d6eb0bc83ba112b8c1b03b212641669c002
parente4e3ea4fd58cbbe462368abde728f9443f01de19 (diff)
downloaddimension-c6612fb215d71ac2bea3b614786cf585cd1a6c74.tar.xz
Clean up some dmnsn_new_*() functions.
Rather than special-case every failed memory allocation, just make dmnsn_delete_*() more robust and call it.
-rw-r--r--libdimension/canvas.c8
-rw-r--r--libdimension/dimension/array.h21
-rw-r--r--libdimension/object.c2
-rw-r--r--libdimension/progress.c70
4 files changed, 37 insertions, 64 deletions
diff --git a/libdimension/canvas.c b/libdimension/canvas.c
index 1d74a33..eacd8f6 100644
--- a/libdimension/canvas.c
+++ b/libdimension/canvas.c
@@ -34,15 +34,15 @@ dmnsn_new_canvas(unsigned int x, unsigned int y)
canvas->x = x;
canvas->y = y;
+ /* Allocate room for the optimizers */
+ canvas->optimizers = dmnsn_new_array(sizeof(dmnsn_canvas_optimizer));
+
/* Allocate the pixels */
canvas->pixels = malloc(sizeof(dmnsn_color)*x*y);
if (!canvas->pixels) {
- free(canvas);
+ dmnsn_delete_canvas(canvas);
return NULL;
}
-
- /* Allocate room for the optimizers */
- canvas->optimizers = dmnsn_new_array(sizeof(dmnsn_canvas_optimizer));
}
return canvas;
diff --git a/libdimension/dimension/array.h b/libdimension/dimension/array.h
index d962d42..1b3771d 100644
--- a/libdimension/dimension/array.h
+++ b/libdimension/dimension/array.h
@@ -36,6 +36,16 @@ typedef struct {
size_t obj_size, length, capacity;
} dmnsn_array;
+/* Delete an array */
+DMNSN_INLINE void
+dmnsn_delete_array(dmnsn_array *array)
+{
+ if (array) {
+ free(array->ptr);
+ free(array);
+ }
+}
+
/* Array allocation never returns NULL - if dmnsn_new_array returns, it
succeeded */
DMNSN_INLINE dmnsn_array *
@@ -50,6 +60,7 @@ dmnsn_new_array(size_t obj_size)
/* Allocate the memory */
array->ptr = malloc(array->capacity*array->obj_size);
if (!array->ptr) {
+ dmnsn_delete_array(array);
dmnsn_error(DMNSN_SEVERITY_HIGH, "Array allocation failed.");
}
} else {
@@ -59,16 +70,6 @@ dmnsn_new_array(size_t obj_size)
return array;
}
-/* Delete the array */
-DMNSN_INLINE void
-dmnsn_delete_array(dmnsn_array *array)
-{
- if (array) {
- free(array->ptr);
- free(array);
- }
-}
-
/* Get the size of the array */
DMNSN_INLINE size_t
dmnsn_array_size(const dmnsn_array *array)
diff --git a/libdimension/object.c b/libdimension/object.c
index 18d7adb..bc758ef 100644
--- a/libdimension/object.c
+++ b/libdimension/object.c
@@ -27,7 +27,7 @@ dmnsn_new_intersection()
{
dmnsn_intersection *intersection = malloc(sizeof(dmnsn_intersection));
if (!intersection) {
- dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't allocate an intersection object.");
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't allocate an intersection.");
}
return intersection;
}
diff --git a/libdimension/progress.c b/libdimension/progress.c
index 18c462f..b466111 100644
--- a/libdimension/progress.c
+++ b/libdimension/progress.c
@@ -37,71 +37,43 @@ dmnsn_new_progress()
progress->elements = dmnsn_new_array(sizeof(dmnsn_progress_element));
dmnsn_array_push(progress->elements, &element);
- /* Allocate space for the rwlock, condition variable, and mutex */
+ /* Initialize the rwlock, condition variable, and mutex */
+
+ progress->rwlock = NULL;
+ progress->mutex = NULL;
+ progress->cond = NULL;
progress->rwlock = malloc(sizeof(pthread_rwlock_t));
if (!progress->rwlock) {
- dmnsn_delete_array(progress->elements);
- free(progress);
+ dmnsn_delete_progress(progress);
+ return NULL;
+ }
+ if (pthread_rwlock_init(progress->rwlock, NULL) != 0) {
+ dmnsn_delete_progress(progress);
return NULL;
}
progress->cond = malloc(sizeof(pthread_cond_t));
if (!progress->cond) {
- free(progress->rwlock);
- dmnsn_delete_array(progress->elements);
- free(progress);
+ dmnsn_delete_progress(progress);
return NULL;
}
-
- progress->mutex = malloc(sizeof(pthread_mutex_t));
- if (!progress->mutex) {
- free(progress->rwlock);
- free(progress->cond);
- dmnsn_delete_array(progress->elements);
- free(progress);
+ if (pthread_cond_init(progress->cond, NULL) != 0) {
+ dmnsn_delete_progress(progress);
return NULL;
}
- /* Initialize the rwlock, condition variable, and mutex */
-
- if (pthread_rwlock_init(progress->rwlock, NULL) != 0) {
- free(progress->rwlock);
- free(progress->mutex);
- free(progress->cond);
- dmnsn_delete_array(progress->elements);
- free(progress);
- return NULL;
- }
- if (pthread_cond_init(progress->cond, NULL) != 0) {
- if (pthread_rwlock_destroy(progress->rwlock) != 0) {
- dmnsn_error(DMNSN_SEVERITY_LOW,
- "Leaking rwlock in failed allocation.");
- }
- free(progress->rwlock);
- free(progress->mutex);
- free(progress->cond);
- dmnsn_delete_array(progress->elements);
- free(progress);
+ progress->mutex = malloc(sizeof(pthread_mutex_t));
+ if (!progress->mutex) {
+ dmnsn_delete_progress(progress);
return NULL;
}
if (pthread_mutex_init(progress->mutex, NULL) != 0) {
- if (pthread_rwlock_destroy(progress->rwlock) != 0) {
- dmnsn_error(DMNSN_SEVERITY_LOW,
- "Leaking rwlock in failed allocation.");
- }
- if (pthread_cond_destroy(progress->cond) != 0) {
- dmnsn_error(DMNSN_SEVERITY_LOW,
- "Leaking condition variable in failed allocation.");
- }
- free(progress->rwlock);
- free(progress->mutex);
- free(progress->cond);
- dmnsn_delete_array(progress->elements);
- free(progress);
+ dmnsn_delete_progress(progress);
return NULL;
}
}
+
return progress;
}
@@ -111,13 +83,13 @@ void
dmnsn_delete_progress(dmnsn_progress *progress)
{
if (progress) {
- if (pthread_rwlock_destroy(progress->rwlock) != 0) {
+ if (progress->rwlock && pthread_rwlock_destroy(progress->rwlock) != 0) {
dmnsn_error(DMNSN_SEVERITY_LOW, "Leaking rwlock.");
}
- if (pthread_mutex_destroy(progress->mutex) != 0) {
+ if (progress->mutex && pthread_mutex_destroy(progress->mutex) != 0) {
dmnsn_error(DMNSN_SEVERITY_LOW, "Leaking mutex.");
}
- if (pthread_cond_destroy(progress->cond) != 0) {
+ if (progress->cond && pthread_cond_destroy(progress->cond) != 0) {
dmnsn_error(DMNSN_SEVERITY_LOW, "Leaking condition variable.");
}