]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-sql: Fix the new sql_db refcounting to work with sql-db-cache
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Sun, 15 Sep 2019 20:45:30 +0000 (23:45 +0300)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 16 Sep 2019 08:00:54 +0000 (08:00 +0000)
src/lib-sql/sql-api-private.h
src/lib-sql/sql-api.c
src/lib-sql/sql-db-cache.c

index a4115a1ec09f3baf9ce38790de64e9319ef5e421..022c5e9e391c61030a5d56715b4e70301c6607b4 100644 (file)
@@ -69,6 +69,7 @@ struct sql_db_vfuncs {
        int (*init_full)(const struct sql_settings *set, struct sql_db **db_r,
                         const char **error);
        void (*deinit)(struct sql_db *db);
+       void (*unref)(struct sql_db *db);
 
        int (*connect)(struct sql_db *db);
        void (*disconnect)(struct sql_db *db);
index d2da70c9ff5798c0091400314c8aa48e43d21165..39b2913b29d0e276f76a0d659475f71004a6c0fc 100644 (file)
@@ -119,6 +119,8 @@ void sql_unref(struct sql_db **_db)
 
        *_db = NULL;
 
+       if (db->v.unref != NULL)
+               db->v.unref(db);
        if (--db->refcount > 0)
                return;
 
index c87cdfb6411206f27db556c0a36d026f64668aa1..b2fb9fb46159a31bd28cff80ffd7d44692098efd 100644 (file)
@@ -27,7 +27,7 @@ struct sql_db_cache {
 
 static MODULE_CONTEXT_DEFINE_INIT(sql_db_cache_module, &sql_db_module_register);
 
-static void sql_db_cache_db_deinit(struct sql_db *db)
+static void sql_db_cache_db_unref(struct sql_db *db)
 {
        struct sql_db_cache_context *ctx = SQL_DB_CACHE_CONTEXT(db);
        struct sql_db_cache_context *head_ctx;
@@ -35,6 +35,8 @@ static void sql_db_cache_db_deinit(struct sql_db *db)
        if (--ctx->refcount > 0)
                return;
 
+       i_assert(db->refcount == 2);
+
        ctx->cache->unused_count++;
        if (ctx->cache->unused_tail == NULL)
                ctx->cache->unused_tail = db;
@@ -73,13 +75,17 @@ static void sql_db_cache_free_tail(struct sql_db_cache *cache)
        struct sql_db_cache_context *ctx;
 
        db = cache->unused_tail;
+       i_assert(db->refcount == 1);
+
        ctx = SQL_DB_CACHE_CONTEXT(db);
        sql_db_cache_unlink(ctx);
        hash_table_remove(cache->dbs, ctx->key);
 
        i_free(ctx->key);
-       ctx->orig_deinit(db);
        i_free(ctx);
+
+       db->v.unref = NULL;
+       sql_unref(&db);
 }
 
 static void sql_db_cache_drop_oldest(struct sql_db_cache *cache)
@@ -116,13 +122,14 @@ int sql_db_cache_new(struct sql_db_cache *cache, const struct sql_settings *set,
                ctx->cache = cache;
                ctx->key = key;
                ctx->orig_deinit = db->v.deinit;
-               db->v.deinit = sql_db_cache_db_deinit;
+               db->v.unref = sql_db_cache_db_unref;
 
                MODULE_CONTEXT_SET(db, sql_db_cache_module, ctx);
                hash_table_insert(cache->dbs, ctx->key, db);
        }
 
        ctx->refcount++;
+       sql_ref(db);
        *db_r = db;
        return 0;
 }