Add per-thread db handles to guard against SQLITE_MISUSE

This commit is contained in:
Ron Pedde 2007-10-13 22:03:52 +00:00
parent 6df87878a5
commit 43c234e666
3 changed files with 87 additions and 29 deletions

View File

@ -62,11 +62,11 @@
/* Globals */
static sqlite *db_sqlite2_songs; /**< Database that holds the mp3 info */
static pthread_mutex_t db_sqlite2_mutex = PTHREAD_MUTEX_INITIALIZER; /**< sqlite not reentrant */
static sqlite_vm *db_sqlite2_pvm;
static int db_sqlite2_reload=0;
static char *db_sqlite2_enum_query;
static pthread_key_t db_sqlite2_key;
static char db_sqlite2_path[PATH_MAX + 1];
@ -80,6 +80,38 @@ extern char *db_sqlite2_initial1;
extern char *db_sqlite2_initial2;
int db_sqlite2_enum_begin_helper(char **pe);
/**
* get (or create) the db handle
*/
sqlite *db_sqlite2_handle(void) {
sqlite *pdb = NULL;
char *perr;
char *pe = NULL;
pdb = (sqlite *)pthread_getspecific(db_sqlite2_key);
if(pdb == NULL) { /* don't have a handle yet */
if((pdb = sqlite_open(db_sqlite2_path,0666,&perr)) == NULL) {
db_get_error(&pe,DB_E_SQL_ERROR,perr);
DPRINTF(E_FATAL,L_DB,"db_sqlite2_open: %s (%s)\n",perr,
db_sqlite2_path);
sqlite_freemem(perr);
db_sqlite2_unlock();
return NULL;
}
sqlite_busy_timeout(pdb,30000); /* 30 seconds */
pthread_setspecific(db_sqlite2_key,(void*)pdb);
}
return pdb;
}
/**
* free a thread-specific db handle
*/
void db_sqlite2_freedb(sqlite *pdb) {
sqlite_close(pdb);
}
/**
* lock the db_mutex
*/
@ -130,15 +162,17 @@ void db_sqlite2_vmfree(char *query) {
* @returns DB_E_SUCCESS on success
*/
int db_sqlite2_open(char **pe, char *dsn) {
sqlite *pdb;
char *perr;
int ver;
int err;
pthread_key_create(&db_sqlite2_key, (void*)db_sqlite2_freedb);
snprintf(db_sqlite2_path,sizeof(db_sqlite2_path),"%s/songs.db",dsn);
db_sqlite2_lock();
db_sqlite2_songs=sqlite_open(db_sqlite2_path,0666,&perr);
if(!db_sqlite2_songs) {
pdb=sqlite_open(db_sqlite2_path,0666,&perr);
if(!pdb) {
db_get_error(pe,DB_E_SQL_ERROR,perr);
DPRINTF(E_LOG,L_DB,"db_sqlite2_open: %s (%s)\n",perr,
db_sqlite2_path);
@ -146,8 +180,7 @@ int db_sqlite2_open(char **pe, char *dsn) {
db_sqlite2_unlock();
return DB_E_SQL_ERROR;
}
sqlite_busy_timeout(db_sqlite2_songs,30000); /* 30 seconds */
sqlite_close(pdb);
db_sqlite2_unlock();
err = db_sql_fetch_int(pe,&ver,"select value from config where "
@ -176,9 +209,6 @@ int db_sqlite2_open(char **pe, char *dsn) {
* close the database
*/
int db_sqlite2_close(void) {
db_sqlite2_lock();
sqlite_close(db_sqlite2_songs);
db_sqlite2_unlock();
return DB_E_SUCCESS;
}
@ -205,7 +235,7 @@ int db_sqlite2_exec(char **pe, int loglevel, char *fmt, ...) {
DPRINTF(E_DBG,L_DB,"Executing: %s\n",query);
db_sqlite2_lock();
err=sqlite_exec(db_sqlite2_songs,query,NULL,NULL,&perr);
err=sqlite_exec(db_sqlite2_handle(),query,NULL,NULL,&perr);
if(err != SQLITE_OK) {
db_get_error(pe,DB_E_SQL_ERROR,perr);
@ -214,7 +244,7 @@ int db_sqlite2_exec(char **pe, int loglevel, char *fmt, ...) {
DPRINTF(loglevel,L_DB,"Error: %s\n",perr);
sqlite_freemem(perr);
} else {
DPRINTF(E_DBG,L_DB,"Rows: %d\n",sqlite_changes(db_sqlite2_songs));
DPRINTF(E_DBG,L_DB,"Rows: %d\n",sqlite_changes(db_sqlite2_handle()));
}
sqlite_freemem(query);
@ -246,7 +276,7 @@ int db_sqlite2_enum_begin_helper(char **pe) {
DPRINTF(E_DBG,L_DB,"Executing: %s\n",db_sqlite2_enum_query);
err=sqlite_compile(db_sqlite2_songs,db_sqlite2_enum_query,
err=sqlite_compile(db_sqlite2_handle(),db_sqlite2_enum_query,
&ptail,&db_sqlite2_pvm,&perr);
if(err != SQLITE_OK) {
@ -430,7 +460,7 @@ int db_sqlite2_event(int event_type) {
*/
int db_sqlite2_insert_id(void) {
return sqlite_last_insert_rowid(db_sqlite2_songs);
return sqlite_last_insert_rowid(db_sqlite2_handle());
}

View File

@ -62,7 +62,6 @@
/* Globals */
static sqlite3 *db_sqlite3_songs; /**< Database that holds the mp3 info */
static pthread_mutex_t db_sqlite3_mutex = PTHREAD_MUTEX_INITIALIZER; /**< sqlite not reentrant */
static sqlite3_stmt *db_sqlite3_stmt;
static const char *db_sqlite3_ptail;
@ -70,7 +69,7 @@ static int db_sqlite3_finalized;
static int db_sqlite3_reload=0;
static char *db_sqlite3_enum_query=NULL;
static char **db_sqlite3_row = NULL;
static pthread_key_t db_sqlite3_key;
static char db_sqlite3_path[PATH_MAX + 1];
#define DB_SQLITE3_VERSION 13
@ -85,6 +84,36 @@ int db_sqlite3_enum_begin_helper(char **pe);
/**
* get (or create) the db handle
*/
sqlite3 *db_sqlite3_handle(void) {
sqlite3 *pdb = NULL;
char *pe = NULL;
pdb = (sqlite3*)pthread_getspecific(db_sqlite3_key);
if(pdb == NULL) { /* don't have a handle yet */
DPRINTF(E_DBG,L_DB,"Creating new db handle\n");
if(sqlite3_open(db_sqlite3_path,&pdb) != SQLITE_OK) {
db_get_error(&pe,DB_E_SQL_ERROR,sqlite3_errmsg(pdb));
DPRINTF(E_FATAL,L_DB,"db_sqlite3_open: %s (%s)\n",pe,db_sqlite3_path);
db_sqlite3_unlock();
return NULL;
}
sqlite3_busy_timeout(pdb,30000); /* 30 seconds */
pthread_setspecific(db_sqlite3_key,(void*)pdb);
}
return pdb;
}
/**
* free a thread-specific db handle
*/
void db_sqlite3_freedb(sqlite3 *pdb) {
sqlite3_close(pdb);
}
/**
* lock the db_mutex
*/
@ -133,19 +162,20 @@ void db_sqlite3_vmfree(char *query) {
int db_sqlite3_open(char **pe, char *dsn) {
int ver;
int err;
sqlite3 *pdb;
pthread_key_create(&db_sqlite3_key, (void*)db_sqlite3_freedb);
snprintf(db_sqlite3_path,sizeof(db_sqlite3_path),"%s/songs3.db",dsn);
db_sqlite3_lock();
if(sqlite3_open(db_sqlite3_path,&db_sqlite3_songs) != SQLITE_OK) {
db_get_error(pe,DB_E_SQL_ERROR,sqlite3_errmsg(db_sqlite3_songs));
if(sqlite3_open(db_sqlite3_path,&pdb) != SQLITE_OK) {
db_get_error(pe,DB_E_SQL_ERROR,sqlite3_errmsg(pdb));
DPRINTF(E_LOG,L_DB,"db_sqlite3_open: %s (%s)\n",pe ? *pe : "Unknown",
db_sqlite3_path);
db_sqlite3_unlock();
return DB_E_SQL_ERROR;
}
sqlite3_busy_timeout(db_sqlite3_songs,30000); /* 30 seconds */
sqlite3_close(pdb);
db_sqlite3_unlock();
err = db_sql_fetch_int(pe,&ver,"select value from config where "
@ -171,9 +201,7 @@ int db_sqlite3_open(char **pe, char *dsn) {
* close the database
*/
int db_sqlite3_close(void) {
db_sqlite3_lock();
sqlite3_close(db_sqlite3_songs);
db_sqlite3_unlock();
/* this doens't actually make much sense, as the closes get done by the threads */
return DB_E_SUCCESS;
}
@ -201,7 +229,7 @@ int db_sqlite3_exec(char **pe, int loglevel, char *fmt, ...) {
DPRINTF(E_DBG,L_DB,"Executing: %s\n",query);
err=sqlite3_exec(db_sqlite3_songs,query,NULL,NULL,&perr);
err=sqlite3_exec(db_sqlite3_handle(),query,NULL,NULL,&perr);
if(err != SQLITE_OK) {
db_get_error(pe,DB_E_SQL_ERROR,perr);
@ -210,7 +238,7 @@ int db_sqlite3_exec(char **pe, int loglevel, char *fmt, ...) {
DPRINTF(loglevel,L_DB,"Error: %s\n",perr);
sqlite3_free(perr);
} else {
DPRINTF(E_DBG,L_DB,"Rows: %d\n",sqlite3_changes(db_sqlite3_songs));
DPRINTF(E_DBG,L_DB,"Rows: %d\n",sqlite3_changes(db_sqlite3_handle()));
}
sqlite3_free(query);
@ -243,11 +271,11 @@ int db_sqlite3_enum_begin_helper(char **pe) {
*((int*)NULL) = 1;
DPRINTF(E_DBG,L_DB,"Executing: %s\n",db_sqlite3_enum_query);
err=sqlite3_prepare(db_sqlite3_songs,db_sqlite3_enum_query,-1,
err=sqlite3_prepare(db_sqlite3_handle(),db_sqlite3_enum_query,-1,
&db_sqlite3_stmt,&db_sqlite3_ptail);
if(err != SQLITE_OK) {
db_get_error(pe,DB_E_SQL_ERROR,sqlite3_errmsg(db_sqlite3_songs));
db_get_error(pe,DB_E_SQL_ERROR,sqlite3_errmsg(db_sqlite3_handle()));
sqlite3_free(db_sqlite3_enum_query);
db_sqlite3_enum_query=NULL;
db_sqlite3_unlock();
@ -325,7 +353,7 @@ int db_sqlite3_enum_fetch(char **pe, SQL_ROW *pr) {
free(db_sqlite3_row);
db_sqlite3_row = NULL;
db_get_error(pe,DB_E_SQL_ERROR,sqlite3_errmsg(db_sqlite3_songs));
db_get_error(pe,DB_E_SQL_ERROR,sqlite3_errmsg(db_sqlite3_handle()));
DPRINTF(E_SPAM,L_DB,"Finalizing statement: %08X\n",db_sqlite3_stmt);
sqlite3_finalize(db_sqlite3_stmt);
db_sqlite3_finalized=1;
@ -352,7 +380,7 @@ int db_sqlite3_enum_end(char **pe) {
DPRINTF(E_SPAM,L_DB,"Finalizing statement: %08X\n",db_sqlite3_stmt);
err = sqlite3_finalize(db_sqlite3_stmt);
if(err != SQLITE_OK) {
db_get_error(pe,DB_E_SQL_ERROR,sqlite3_errmsg(db_sqlite3_songs));
db_get_error(pe,DB_E_SQL_ERROR,sqlite3_errmsg(db_sqlite3_handle()));
db_sqlite3_unlock();
return DB_E_SQL_ERROR;
}
@ -472,7 +500,7 @@ int db_sqlite3_insert_id(void) {
int result;
db_sqlite3_lock();
result = (int)sqlite3_last_insert_rowid(db_sqlite3_songs);
result = (int)sqlite3_last_insert_rowid(db_sqlite3_handle());
db_sqlite3_unlock();
return result;

View File

@ -273,7 +273,7 @@ void rsp_info(WS_CONNINFO *pwsc, PRIVINFO *ppi) {
/* info block */
xml_push(pxml,"info");
xml_output(pxml,"count","%d",pi_db_count());
xml_output(pxml,"count","%d",pi_db_count_items(COUNT_SONGS));
xml_output(pxml,"rsp-version","%s",RSP_VERSION);
xml_output(pxml,"server-version","%s",pi_server_ver());