]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-dict: Keep a linked list of all transactions in dict.
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 29 Mar 2017 10:27:32 +0000 (13:27 +0300)
committerGitLab <gitlab@git.dovecot.net>
Wed, 29 Mar 2017 17:17:18 +0000 (20:17 +0300)
This helps debugging if a transaction is leaked.

src/lib-dict/dict-private.h
src/lib-dict/dict.c

index 3668019340067530795abccf85c379e1bbc31f9d..d147c2d593a6162b70f601c91c38f499b77a297a 100644 (file)
@@ -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;
 
index cc28aa94d3a47b518ac4e6a9b6b691ee6af5cf73..dedda65a2c2dd604ea3ca25fa1ac1456f5e02ce8 100644 (file)
@@ -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);
 }