Repository: valkey-io/valkey
File: src/functions.c (C)

Code before:
    dictEmpty(lib_ctx->libraries, callback);
    dictIterator *iter = dictGetIterator(lib_ctx->engines_stats);
    dictEntry *entry = NULL;
    while ((entry = dictNext(iter))) {
        functionsLibEngineStats *stats = dictGetVal(entry);
        stats->n_functions = 0;
        stats->n_lib = 0;
    }
    dictReleaseIterator(iter);
    lib_ctx->cache_memory = 0;
}

static void resetEngineFunctionEnvCallback(scriptingEngine *engine, void *context) {
    int async = context != NULL;
    callableLazyEnvReset *callback = scriptingEngineCallResetEnvFunc(engine, VMSE_FUNCTION, async);

    if (async) {
        list *callbacks = context;
        listAddNodeTail(callbacks, callback);
    }
}

void functionsLibCtxReleaseCurrent(int async, void(callback)(dict *)) {
    if (async) {
        list *engine_callbacks = listCreate();
        scriptingEngineManagerForEachEngine(resetEngineFunctionEnvCallback, engine_callbacks);
        freeFunctionsAsync(curr_functions_lib_ctx, engine_callbacks);
    } else {
        functionsLibCtxFree(curr_functions_lib_ctx, callback, NULL);
        scriptingEngineManagerForEachEngine(resetEngineFunctionEnvCallback, NULL);
    }
}

/* Free the given functions ctx */
static void functionsLibCtxFreeGeneric(functionsLibCtx *functions_lib_ctx, int async) {
    if (async) {
        freeFunctionsAsync(functions_lib_ctx, NULL);
    } else {
        functionsLibCtxFree(functions_lib_ctx, NULL, NULL);
    }
}

void functionReset(int async, void(callback)(dict *)) {
    functionsLibCtxReleaseCurrent(async, callback);
    functionsInit();
}

/* Free the given functions ctx */
void functionsLibCtxFree(functionsLibCtx *functions_lib_ctx, void(callback)(dict *), list *engine_callbacks) {
    functionsLibCtxClear(functions_lib_ctx, callback);
    dictRelease(functions_lib_ctx->functions);

Review comment (suggestion):
`resetEngineFunctionEnvCallback` is misleading, it doesn't reset or act as a callback. It collects reset callbacks. Suggest renaming to `collectEngineResetCallbacks` for clarity.

Code after:
    dictEmpty(lib_ctx->libraries, callback);
    dictIterator *iter = dictGetIterator(lib_ctx->engines_stats);
    dictEntry *entry = NULL;
    while ((entry = dictNext(iter))) {
        functionsLibEngineStats *stats = dictGetVal(entry);
        stats->n_functions = 0;
        stats->n_lib = 0;
    }
    dictReleaseIterator(iter);
    lib_ctx->cache_memory = 0;
}

static void resetEngineOrCollectResetCallbacks(scriptingEngine *engine, void *context) {
    int async = context != NULL;
    callableLazyEnvReset *callback = scriptingEngineCallResetEnvFunc(engine, VMSE_FUNCTION, async);

    if (async) {
        list *callbacks = context;
        listAddNodeTail(callbacks, callback);
    }
}

void functionsLibCtxReleaseCurrent(int async, void(callback)(dict *)) {
    if (async) {
        list *engine_callbacks = listCreate();
        scriptingEngineManagerForEachEngine(resetEngineOrCollectResetCallbacks, engine_callbacks);
        freeFunctionsAsync(curr_functions_lib_ctx, engine_callbacks);
    } else {
        functionsLibCtxFree(curr_functions_lib_ctx, callback, NULL);
        scriptingEngineManagerForEachEngine(resetEngineOrCollectResetCallbacks, NULL);
    }
}

/* Free the given functions ctx */
static void functionsLibCtxFreeGeneric(functionsLibCtx *functions_lib_ctx, int async) {
    if (async) {
        freeFunctionsAsync(functions_lib_ctx, NULL);
    } else {
        functionsLibCtxFree(functions_lib_ctx, NULL, NULL);
    }
}

void functionReset(int async, void(callback)(dict *)) {
    functionsLibCtxReleaseCurrent(async, callback);
    functionsInit();
}

/* Free the given functions ctx */
void functionsLibCtxFree(functionsLibCtx *functions_lib_ctx, void(callback)(dict *), list *engine_callbacks) {
    functionsLibCtxClear(functions_lib_ctx, callback);
    dictRelease(functions_lib_ctx->functions);