1
0
mirror of https://github.com/coturn/coturn.git synced 2025-10-24 20:41:03 +02:00

dbd_sqlite: Don't shutdown sqlite3 db during init

Ref https://www.sqlite.org/c3ref/initialize.html:

    The sqlite3_initialize() interface is threadsafe, but
    sqlite3_shutdown() is not.

We currently call `sqlite3_shutdown` from all threads as part of
`sqlite_init_multithreaded`, and this has been observed to have
adversarial effects during startup if many threads receive their first
inbound request at the same time. The apparent motivation behind
calling shutdown is to make the subsequent calls to `sqlite3_config`
succeed, since these ordinarily return SQLITE_MISUSE if called
multiple times. However, this function is also documented to not be
thread safe, so introduce a barrier that ensures we only initialize
once over all threads.
This commit is contained in:
Arne Georg Gisnås Gleditsch 2021-09-20 11:49:34 +02:00
parent 4c059b0d3b
commit 8d66122d91

View File

@ -45,11 +45,13 @@
//////////////////////////////////////////////////
static pthread_mutex_t rc_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t rc_cond = PTHREAD_COND_INITIALIZER;
static int read_threads = 0;
static int write_level = 0;
static pthread_t write_thread = 0;
static int sqlite_initialized = 0;
static void sqlite_lock(int write)
{
@ -96,11 +98,12 @@ static void sqlite_unlock(int write)
//////////////////////////////////////////////////
static int sqlite_init_multithreaded(void) {
if (sqlite_initialized) {
return 0;
}
sqlite_initialized = 1;
#if defined(SQLITE_CONFIG_MULTITHREAD)
sqlite3_shutdown();
if (sqlite3_threadsafe() > 0) {
int retCode = sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
if (retCode != SQLITE_OK) {
@ -110,6 +113,7 @@ static int sqlite_init_multithreaded(void) {
return -1;
}
}
sqlite3_initialize();
} else {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Your SQLite database is not compiled to be threadsafe.\n");
return -1;
@ -180,6 +184,8 @@ static sqlite3 * get_sqlite_connection(void) {
sqlite3 *sqliteconnection = (sqlite3 *)pthread_getspecific(connection_key);
if(!sqliteconnection) {
pthread_mutex_lock(&init_mutex);
fix_user_directory(pud->userdb);
sqlite_init_multithreaded();
int rc = sqlite3_open(pud->userdb, &sqliteconnection);
@ -201,6 +207,8 @@ static sqlite3 * get_sqlite_connection(void) {
if(sqliteconnection) {
(void) pthread_setspecific(connection_key, sqliteconnection);
}
pthread_mutex_unlock(&init_mutex);
}
return sqliteconnection;
}