From 8fb3b27efa707f53bf0b0d74aec0e055f0d10e96 Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Mon, 12 Jun 2023 15:38:11 -0700 Subject: til_module_context: refcount module contexts This becomes necessary in a world with externall-discoverable-on-stream-contexts that can be arbitrarily referenced by other contexts. There will probably be more complexity necessary for invalidating references, but this is a start. --- src/til_module_context.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- src/til_module_context.h | 5 ++++- 2 files changed, 46 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/til_module_context.c b/src/til_module_context.c index 98a32cd..092e3e1 100644 --- a/src/til_module_context.c +++ b/src/til_module_context.c @@ -50,6 +50,7 @@ void * til_module_context_new(const til_module_t *module, size_t size, til_strea module_context->ticks = ticks; module_context->n_cpus = n_cpus; module_context->setup = til_setup_ref(setup); + module_context->refcount = 1; return module_context; } @@ -60,13 +61,13 @@ void * til_module_context_new(const til_module_t *module, size_t size, til_strea * * Note this replaces til_module_destroy_context(), which has been removed. */ -void * til_module_context_free(til_module_context_t *module_context) +static inline void * module_context_free(til_module_context_t *module_context) { til_stream_t *stream; til_setup_t *setup; - if (!module_context) - return NULL; + assert(module_context); + assert(!module_context->refcount); stream = module_context->stream; setup = module_context->setup; @@ -87,3 +88,41 @@ void * til_module_context_free(til_module_context_t *module_context) return NULL; } + + +/* bump refcount on context */ +void * til_module_context_ref(til_module_context_t *module_context) +{ + assert(module_context); + + module_context->refcount++; + + return module_context; +} + + +/* unref the module_context, returns non-NULL when module_context persists */ +static void * til_module_context_unref(til_module_context_t *module_context) +{ +/* XXX this is kept private until there's a real use case in need of the distinct return values vs. free. + * til_setup is the same way, which this is basically mirroring + */ + if (!module_context) + return NULL; + + assert(module_context->refcount > 0); + + module_context->refcount--; + if (!module_context->refcount) + return module_context_free(module_context); + + return module_context; +} + + +void * til_module_context_free(til_module_context_t *module_context) +{ + (void) til_module_context_unref(module_context); + + return NULL; +} diff --git a/src/til_module_context.h b/src/til_module_context.h index cbbfb8e..05f77ab 100644 --- a/src/til_module_context.h +++ b/src/til_module_context.h @@ -8,16 +8,19 @@ typedef struct til_stream_t til_stream_t; struct til_module_context_t { const til_module_t *module; - til_stream_t *stream; /* optional stream this context is part of */ + til_stream_t *stream; /* optional stream this context is part of (module_contexts are discoverable @setup->path when part of a stream) */ unsigned seed; unsigned ticks; unsigned n_cpus; til_setup_t *setup; /* Baked setup this context was made from, reffed by context. * Always present as it provides the path, which is generally derived from a settings instance. */ + + unsigned refcount; }; void * til_module_context_new(const til_module_t *module, size_t size, til_stream_t *stream, unsigned seed, unsigned ticks, unsigned n_cpus, til_setup_t *setup); +void * til_module_context_ref(til_module_context_t *module_context); void * til_module_context_free(til_module_context_t *module_context); #endif -- cgit v1.2.3