summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/stage.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/src/stage.c b/src/stage.c
index b072050..7c07877 100644
--- a/src/stage.c
+++ b/src/stage.c
@@ -32,6 +32,7 @@ struct stage_t {
unsigned active:1; /* stage is active */
unsigned locked:1; /* stage is locked */
unsigned dirty:1; /* stage is dirty (since last render) */
+ unsigned allocated:1; /* stage is allocated by libstage, needs freeing. */
const stage_ops_t *ops; /* ops for operating on this stage's object */
void *object; /* this stage's object */
@@ -70,6 +71,8 @@ static stage_t * _stage_new(const char *name, const stage_ops_t *ops, void *obje
for (int i = 0; i < STAGE_LAYERS_MAX; i++)
dll_init(&stage->layers[i]);
+ stage->allocated = 1;
+
return _stage_set_object(stage, name, ops, object);
}
@@ -77,12 +80,20 @@ static stage_t * _stage_new(const char *name, const stage_ops_t *ops, void *obje
/* free a stage, no list manipulation occurs, this is purely cleanup of the stage and its object */
static void _stage_free(stage_t *stage)
{
+ unsigned allocated;
+
assert(stage);
+ /* briefly cache stage->allocated, since free_func() may very well free
+ * the stage when !allocated.
+ */
+ allocated = stage->allocated;
+
if (stage->ops->free_func)
stage->ops->free_func(stage, stage->object);
- free(stage);
+ if (allocated)
+ free(stage);
}
© All Rights Reserved