From 82083452bf6f943c6958876317198690970c4d3e Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Fri, 29 May 2020 13:19:40 -0700 Subject: libstage: support caller-supplied stage memory When !stage_conf_t.replace and stage_conf_t.stage is non-NULL, stage_conf_t.stage will be used for the stage memory in stage_new() instead of allocating some. It's up to the caller to free this memory as needed, which may safely be done from stage_ops_t.free_func() if needed. Note that at this time there's no way for external callers to actually know the stage_t size, as it's entirely opaque. A future commit will expose a padded variant of the struct, exposing its size appropriately without making it completely public. --- src/stage.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/stage.c b/src/stage.c index 7c07877..a714f1f 100644 --- a/src/stage.c +++ b/src/stage.c @@ -58,21 +58,23 @@ static stage_t * _stage_set_object(stage_t *stage, const char *name, const stage } -/* allocate a stage, this purely creates a stage in isolation and assigns its associated name, object and functions */ -static stage_t * _stage_new(const char *name, const stage_ops_t *ops, void *object) +/* Create a new stage, this purely creates a stage in isolation and assigns its associated name, object and functions. + * If stage is non-NULL, now allocation is performed and it's used instead. + */ +static stage_t * _stage_new(stage_t *stage, const char *name, const stage_ops_t *ops, void *object) { - stage_t *stage; + if (!stage) { + stage = calloc(1, sizeof(stage_t)); + if (!stage) + return NULL; - stage = calloc(1, sizeof(stage_t)); - if (!stage) - return NULL; + stage->allocated = 1; + } dll_init(&stage->layer); 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); } @@ -112,7 +114,7 @@ stage_t * stage_new(const stage_conf_t *conf, const stage_ops_t *ops, void *obje if (conf->replace) return stage_replace(conf->stage, conf->name, ops, object); - stage = _stage_new(conf->name, ops, object); + stage = _stage_new(conf->stage, conf->name, ops, object); if (!stage) return NULL; -- cgit v1.2.3