From: Timo Sirainen Date: Wed, 29 Mar 2017 10:27:32 +0000 (+0300) Subject: lib-dict: Keep a linked list of all transactions in dict. X-Git-Tag: 2.3.0.rc1~1852 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5012586ed3a75857ced48302bf0b8a8dc049796a;p=thirdparty%2Fdovecot%2Fcore.git lib-dict: Keep a linked list of all transactions in dict. This helps debugging if a transaction is leaked. --- diff --git a/src/lib-dict/dict-private.h b/src/lib-dict/dict-private.h index 3668019340..d147c2d593 100644 --- a/src/lib-dict/dict-private.h +++ b/src/lib-dict/dict-private.h @@ -51,6 +51,7 @@ struct dict { struct dict_vfuncs v; unsigned int iter_count; unsigned int transaction_count; + struct dict_transaction_context *transactions; }; struct dict_iterate_context { @@ -66,6 +67,7 @@ struct dict_iterate_context { struct dict_transaction_context { struct dict *dict; + struct dict_transaction_context *prev, *next; struct timespec timestamp; diff --git a/src/lib-dict/dict.c b/src/lib-dict/dict.c index cc28aa94d3..dedda65a2c 100644 --- a/src/lib-dict/dict.c +++ b/src/lib-dict/dict.c @@ -2,6 +2,7 @@ #include "lib.h" #include "array.h" +#include "llist.h" #include "str.h" #include "dict-sql.h" #include "dict-private.h" @@ -96,6 +97,7 @@ void dict_deinit(struct dict **_dict) i_assert(dict->iter_count == 0); i_assert(dict->transaction_count == 0); + i_assert(dict->transactions == NULL); dict->v.deinit(dict); } @@ -235,6 +237,7 @@ struct dict_transaction_context *dict_transaction_begin(struct dict *dict) passed as parameter, e.g. it can be dict-fail when transactions are not supported. */ ctx->dict->transaction_count++; + DLLIST_PREPEND(&ctx->dict->transactions, ctx); return ctx; } @@ -285,6 +288,7 @@ int dict_transaction_commit(struct dict_transaction_context **_ctx, i_zero(&result); 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); *error_r = t_strdup(result.error); @@ -301,6 +305,7 @@ void dict_transaction_commit_async(struct dict_transaction_context **_ctx, *_ctx = NULL; i_assert(ctx->dict->transaction_count > 0); ctx->dict->transaction_count--; + 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); @@ -313,6 +318,7 @@ void dict_transaction_rollback(struct dict_transaction_context **_ctx) *_ctx = NULL; i_assert(ctx->dict->transaction_count > 0); ctx->dict->transaction_count--; + DLLIST_REMOVE(&ctx->dict->transactions, ctx); ctx->dict->v.transaction_rollback(ctx); }