From: Aki Tuomi Date: Mon, 2 Mar 2020 18:09:48 +0000 (+0200) Subject: lib-dict: Add async lookup/commit helpers X-Git-Tag: 2.3.11.2~500 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=12067d7cf1d51495cbdadb6c4007977ba3aa243b;p=thirdparty%2Fdovecot%2Fcore.git lib-dict: Add async lookup/commit helpers Simplifies following commits --- diff --git a/src/lib-dict/dict-client.c b/src/lib-dict/dict-client.c index aeed69e5b1..74ee853a52 100644 --- a/src/lib-dict/dict-client.c +++ b/src/lib-dict/dict-client.c @@ -950,9 +950,7 @@ client_dict_lookup_async_callback(struct client_dict_cmd *cmd, cmd->query); } - dict_pre_api_callback(&dict->dict); cmd->api_callback.lookup(&result, cmd->api_callback.context); - dict_post_api_callback(&dict->dict); } static void @@ -1000,7 +998,7 @@ static int client_dict_lookup(struct dict *_dict, pool_t pool, const char *key, i_zero(&lookup); lookup.ret = -2; - client_dict_lookup_async(_dict, key, client_dict_lookup_callback, &lookup); + dict_lookup_async(_dict, key, client_dict_lookup_callback, &lookup); if (lookup.ret == -2) client_dict_wait(_dict); @@ -1322,9 +1320,7 @@ client_dict_transaction_commit_callback(struct client_dict_cmd *cmd, } client_dict_transaction_free(&cmd->trans); - dict_pre_api_callback(&dict->dict); cmd->api_callback.commit(&result, cmd->api_callback.context); - dict_post_api_callback(&dict->dict); } diff --git a/src/lib-dict/dict-redis.c b/src/lib-dict/dict-redis.c index 4ce4dc2b85..3d8fd64b80 100644 --- a/src/lib-dict/dict-redis.c +++ b/src/lib-dict/dict-redis.c @@ -79,17 +79,6 @@ static void redis_input_state_remove(struct redis_dict *dict) array_pop_front(&dict->input_states); } -static void redis_callback(struct redis_dict *dict, - const struct redis_dict_reply *reply, - const struct dict_commit_result *result) -{ - if (reply->callback != NULL) { - dict_pre_api_callback(&dict->dict); - reply->callback(result, reply->context); - dict_post_api_callback(&dict->dict); - } -} - static void redis_disconnected(struct redis_connection *conn, const char *reason) { @@ -103,7 +92,7 @@ redis_disconnected(struct redis_connection *conn, const char *reason) connection_disconnect(&conn->conn); array_foreach(&conn->dict->replies, reply) - redis_callback(conn->dict, reply, &result); + reply->callback(&result, reply->context); array_clear(&conn->dict->replies); array_clear(&conn->dict->input_states); @@ -258,7 +247,7 @@ redis_conn_input_more(struct redis_connection *conn, const char **error_r) const struct dict_commit_result result = { DICT_COMMIT_RET_OK, NULL }; - redis_callback(dict, reply, &result); + reply->callback(&result, reply->context); array_pop_front(&dict->replies); /* if we're running in a dict-ioloop, we're handling a synchronous commit and need to stop now */ diff --git a/src/lib-dict/dict.c b/src/lib-dict/dict.c index 815d6817a4..5a6763b231 100644 --- a/src/lib-dict/dict.c +++ b/src/lib-dict/dict.c @@ -5,8 +5,21 @@ #include "llist.h" #include "ioloop.h" #include "str.h" +#include "ioloop.h" #include "dict-private.h" +struct dict_commit_callback_ctx { + struct dict *dict; + dict_transaction_commit_callback_t *callback; + void *context; +}; + +struct dict_lookup_callback_ctx { + struct dict *dict; + dict_lookup_callback_t *callback; + void *context; +}; + static ARRAY(struct dict *) dict_drivers; static struct dict *dict_driver_lookup(const char *name) @@ -140,6 +153,34 @@ void dict_post_api_callback(struct dict *dict) } } +static void +dict_lookup_callback(const struct dict_lookup_result *result, + void *context) +{ + struct dict_lookup_callback_ctx *ctx = context; + + dict_pre_api_callback(ctx->dict); + ctx->callback(result, ctx->context); + dict_post_api_callback(ctx->dict); + + i_free(ctx); +} + +static void dict_commit_callback(const struct dict_commit_result *result, + void *context) +{ + struct dict_commit_callback_ctx *ctx = context; + + i_assert(result->ret >= 0 || result->error != NULL); + dict_pre_api_callback(ctx->dict); + if (ctx->callback != NULL) + ctx->callback(result, ctx->context); + else if (result->ret < 0) + i_error("dict(%s): Commit failed: %s", + ctx->dict->name, result->error); + dict_post_api_callback(ctx->dict); + i_free(ctx); +} int dict_lookup(struct dict *dict, pool_t pool, const char *key, const char **value_r, const char **error_r) @@ -162,7 +203,12 @@ void dict_lookup_async(struct dict *dict, const char *key, callback(&result, context); return; } - dict->v.lookup_async(dict, key, callback, context); + struct dict_lookup_callback_ctx *lctx = + i_new(struct dict_lookup_callback_ctx, 1); + lctx->dict = dict; + lctx->callback = callback; + lctx->context = context; + dict->v.lookup_async(dict, key, dict_lookup_callback, lctx); } struct dict_iterate_context * @@ -299,6 +345,8 @@ dict_transaction_commit_sync_callback(const struct dict_commit_result *result, int dict_transaction_commit(struct dict_transaction_context **_ctx, const char **error_r) { + struct dict_commit_callback_ctx *cctx = + i_new(struct dict_commit_callback_ctx, 1); struct dict_transaction_context *ctx = *_ctx; struct dict_commit_sync_result result; @@ -308,8 +356,11 @@ int dict_transaction_commit(struct dict_transaction_context **_ctx, i_assert(ctx->dict->transaction_count > 0); ctx->dict->transaction_count--; DLLIST_REMOVE(&ctx->dict->transactions, ctx); - ctx->dict->v.transaction_commit(ctx, FALSE, - dict_transaction_commit_sync_callback, &result); + cctx->dict = ctx->dict; + cctx->callback = dict_transaction_commit_sync_callback; + cctx->context = &result; + + ctx->dict->v.transaction_commit(ctx, FALSE, dict_commit_callback, cctx); *error_r = t_strdup(result.error); i_free(result.error); return result.ret; @@ -319,6 +370,8 @@ void dict_transaction_commit_async(struct dict_transaction_context **_ctx, dict_transaction_commit_callback_t *callback, void *context) { + struct dict_commit_callback_ctx *cctx = + i_new(struct dict_commit_callback_ctx, 1); struct dict_transaction_context *ctx = *_ctx; *_ctx = NULL; @@ -327,7 +380,10 @@ void dict_transaction_commit_async(struct dict_transaction_context **_ctx, DLLIST_REMOVE(&ctx->dict->transactions, ctx); if (callback == NULL) callback = dict_transaction_commit_async_noop_callback; - ctx->dict->v.transaction_commit(ctx, TRUE, callback, context); + cctx->dict = ctx->dict; + cctx->callback = callback; + cctx->context = context; + ctx->dict->v.transaction_commit(ctx, TRUE, dict_commit_callback, cctx); } void dict_transaction_rollback(struct dict_transaction_context **_ctx)