@cryptotaxi247 / netdata-1 / commits / 0819f1779

Add additional database checks during shutdown (#20731)

Do not attempt to release statements if we have closed the databases

Stelios Fragkakis committed Jul 28, 2025 at 20:52 UTC 0819f17790f7362414db228076cae7c34e343fb9
1 file changed +19 -5
src/database/sqlite/sqlite_functions.c
+19 -5
@@ -4,8 +4,8 @@
4
5 #define MAX_PREPARED_THREAD_STATEMENTS (32)
6
7 -SPINLOCK JudyL_thread_stmt_lock = SPINLOCK_INITIALIZER;
8 -Pvoid_t JudyL_thread_stmt_pool = NULL;
7 +static SPINLOCK JudyL_thread_stmt_lock = SPINLOCK_INITIALIZER;
8 +static Pvoid_t JudyL_thread_stmt_pool = NULL;
9
10 struct stmt_pool_s {
11 int count;
@@ -21,6 +21,7 @@ long long def_journal_size_limit = 16777216;
21 SPINLOCK sqlite_spinlock = SPINLOCK_INITIALIZER;
22
23 bool sqlite_library_initialized;
24 +bool sqlite_databases_closed;
25
26 SQLITE_API int sqlite3_exec_monitored(
27 sqlite3 *db, /* An open database */
@@ -189,6 +190,11 @@ static void finalize_and_free_stmt_list(struct stmt_pool_s *stmt_list)
190 // This must be called when the thread terminates
191 void finalize_self_prepared_sql_statements()
192 {
193 + if (__atomic_load_n(&sqlite_databases_closed, __ATOMIC_ACQUIRE))
194 + return;
195 +
196 + spinlock_lock(&sqlite_spinlock);
197 +
198 spinlock_lock(&JudyL_thread_stmt_lock);
199 if (thread_stmt_pool) {
200 Word_t thread_id = thread_stmt_pool->thread_id;
@@ -197,6 +203,8 @@ void finalize_self_prepared_sql_statements()
203 (void)JudyLDel(&JudyL_thread_stmt_pool, thread_id, PJE0);
204 }
205 spinlock_unlock(&JudyL_thread_stmt_lock);
206 +
207 + spinlock_unlock(&sqlite_spinlock);
208 }
209
210 void finalize_all_prepared_sql_statements()
@@ -245,6 +253,9 @@ static void init_thread_stmt_pool(void) {
253
254 int prepare_statement(sqlite3 *database, const char *query, sqlite3_stmt **statement)
255 {
256 + if (__atomic_load_n(&sqlite_databases_closed, __ATOMIC_ACQUIRE))
257 + return SQLITE_MISUSE;
258 +
259 int rc = sqlite3_prepare_v2(database, query, -1, statement, 0);
260 if (rc == SQLITE_OK) {
261 if (!thread_stmt_pool)
@@ -429,11 +440,13 @@ extern sqlite3 *db_context_meta;
440
441 void sqlite_close_databases(void)
442 {
432 - spinlock_lock(&sqlite_spinlock);
433 -
434 - // In case we have statements in the main thread
443 + // In case we have statements in the main thread (we should not)
444 finalize_self_prepared_sql_statements();
445
446 + __atomic_store_n(&sqlite_databases_closed, true, __ATOMIC_RELEASE);
447 +
448 + spinlock_lock(&sqlite_spinlock);
449 +
450 // Finalize pending statements and report any thread that failed
451 // to do it properly
452 finalize_all_prepared_sql_statements();
@@ -484,6 +497,7 @@ int sqlite_library_init(void)
497 nd_log_daemon(
498 NDLP_INFO, "SQLITE: heap memory hard limit %s, soft limit %s", sqlite_hard_limit_mb, sqlite_soft_limit_mb);
499 }
500 + __atomic_store_n(&sqlite_databases_closed, false, __ATOMIC_RELEASE);
501 sqlite_library_initialized = true;
502 spinlock_unlock(&sqlite_spinlock);
503