From bd99aba1ab28288853aa133afc7534126e789332 Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Fri, 29 May 2020 13:05:56 -0700 Subject: libstage: only free stage memory when allocated More preparation for caller-supplied stage memory. As-is this changes nothing functionally since there's no way to supply caller- allocated uninitialized memory to stage_new() yet. There's the .replace capability, but that requires a valid stage in .stage, which could only be gotten correctly via stage_new() originally, so it'll always have the .allocated member set. A future commit will wire up using the .stage member as caller-supplied memory when set in stage_new() without .replace. --- src/stage.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) 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); } -- cgit v1.2.3