From: Timo Sirainen Date: Sun, 15 Sep 2019 20:45:30 +0000 (+0300) Subject: lib-sql: Fix the new sql_db refcounting to work with sql-db-cache X-Git-Tag: 2.3.9~152 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7a0e6f9ca0d11ebfd5ddf94df17ccd8f04e6cea5;p=thirdparty%2Fdovecot%2Fcore.git lib-sql: Fix the new sql_db refcounting to work with sql-db-cache --- diff --git a/src/lib-sql/sql-api-private.h b/src/lib-sql/sql-api-private.h index a4115a1ec0..022c5e9e39 100644 --- a/src/lib-sql/sql-api-private.h +++ b/src/lib-sql/sql-api-private.h @@ -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); diff --git a/src/lib-sql/sql-api.c b/src/lib-sql/sql-api.c index d2da70c9ff..39b2913b29 100644 --- a/src/lib-sql/sql-api.c +++ b/src/lib-sql/sql-api.c @@ -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; diff --git a/src/lib-sql/sql-db-cache.c b/src/lib-sql/sql-db-cache.c index c87cdfb641..b2fb9fb461 100644 --- a/src/lib-sql/sql-db-cache.c +++ b/src/lib-sql/sql-db-cache.c @@ -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; }