diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/stage.c | 13 |
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); } |