star-sp

Random number generators and distributions
git clone git://git.meso-star.fr/star-sp.git
Log | Files | Refs | README | LICENSE

commit 5e7b47c71078d5fba901d7bf3e57e0a6914f66a2
parent 4a9554b0f8d22ea890fe0ae50216bb9ca44054a9
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Sun, 30 Mar 2025 16:09:37 +0200

Fix proxy error handling

There was no clear way of detecting which proxy member variables were
actually initialised and which were not. In the event of an error,
initialised data was released when it should not have been.

Diffstat:
Msrc/ssp_rng_proxy.c | 44+++++++++++++++++++++++++-------------------
1 file changed, 25 insertions(+), 19 deletions(-)

diff --git a/src/ssp_rng_proxy.c b/src/ssp_rng_proxy.c @@ -52,6 +52,8 @@ struct rng_state_cache { int no_wstream; /* Define if the RNG states are no more written to a stream */ int no_rstream; /* Define if the RNG states are no more read from a stream */ + + int is_init; /* Cache initialisation state */ }; CLBK(rng_proxy_cb_T, ARG1(const struct ssp_rng_proxy*)); @@ -170,6 +172,18 @@ error: /******************************************************************************* * Cache of RNG states ******************************************************************************/ +static void +rng_state_cache_release(struct rng_state_cache* cache) +{ + ASSERT(cache); + if(!cache->is_init) return; /* Nothing to release */ + + if(cache->stream) fclose(cache->stream); + if(cache->buffer) MEM_RM(cache->allocator, cache->buffer); + darray_char_release(&cache->state); + darray_char_release(&cache->state_scratch); +} + static res_T rng_state_cache_init (struct mem_allocator* allocator, @@ -184,6 +198,7 @@ rng_state_cache_init darray_char_init(allocator, &cache->state_scratch); cache->allocator = allocator; cache->end_of_cache = STATE_CACHE_CAPACITY; + cache->state_pitch = state_pitch; cache->buffer = MEM_CALLOC(allocator, 1, STATE_CACHE_CAPACITY); if(!cache->buffer) { @@ -191,32 +206,15 @@ rng_state_cache_init goto error; } - cache->stream = fmemopen(cache->buffer, STATE_CACHE_CAPACITY, "w+"); - if(!cache->stream) { - res = RES_IO_ERR; - goto error; - } - cache->read = cache->write = ftell(cache->stream); - cache->state_pitch = state_pitch; + cache->is_init = 1; exit: return res; error: - if(cache->buffer) MEM_RM(allocator, cache->buffer); - if(cache->stream) fclose(cache->stream); + rng_state_cache_release(cache); goto exit; } -static void -rng_state_cache_release(struct rng_state_cache* cache) -{ - ASSERT(cache); - if(cache->stream) fclose(cache->stream); - if(cache->buffer) MEM_RM(cache->allocator, cache->buffer); - darray_char_release(&cache->state); - darray_char_release(&cache->state_scratch); -} - static res_T rng_state_cache_clear(struct rng_state_cache* cache) { @@ -663,6 +661,14 @@ rng_proxy_setup sa_add(proxy->buckets, nbuckets); sa_add(proxy->per_bucket_sequence_id, nbuckets); + /* Clearing allocated memory. This operation is necessary to manage errors and + * identify which data has been initialised and which has not */ + memset(proxy->states, 0, sizeof(*proxy->states)*nbuckets); + memset(proxy->pools, 0, sizeof(*proxy->pools)*nbuckets); + memset(proxy->buckets, 0, sizeof(*proxy->buckets)*nbuckets); + memset(proxy->per_bucket_sequence_id, 0, + sizeof(*proxy->per_bucket_sequence_id)*nbuckets); + FOR_EACH(ibucket, 0, nbuckets) { res = rng_state_cache_init (proxy->allocator, sequence_pitch, proxy->states+ibucket);