#include <switch.h>
#include "private/switch_core_pvt.h"
+static struct {
+ switch_cache_db_handle_t *event_db;
+ switch_queue_t *sql_queue[2];
+ switch_memory_pool_t *memory_pool;
+ switch_event_node_t *event_node;
+ switch_thread_t *thread;
+ int thread_running;
+ switch_bool_t manage;
+ switch_mutex_t *io_mutex;
+ switch_mutex_t *dbh_mutex;
+ switch_hash_t *dbh_hash;
+} sql_manager;
+
#define SWITCH_CORE_DB "core"
/*!
SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t **dbh, const char *file, const char *func, int line)
{
switch_cache_db_connection_options_t options = { {0} };
-
+ switch_status_t r;
+
if (runtime.odbc_dsn && runtime.odbc_user && runtime.odbc_pass) {
options.odbc_options.dsn = runtime.odbc_dsn;
options.odbc_options.user = runtime.odbc_user;
options.odbc_options.pass = runtime.odbc_pass;
- return _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_ODBC, &options, file, func, line);
+ r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_ODBC, &options, file, func, line);
} else {
options.core_db_options.db_path = SWITCH_CORE_DB;
- return _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_CORE_DB, &options, file, func, line);
+ r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_CORE_DB, &options, file, func, line);
}
-}
+ if (r == SWITCH_STATUS_SUCCESS && !(*dbh)->io_mutex) {
+ (*dbh)->io_mutex = sql_manager.io_mutex;
+ }
-static struct {
- switch_cache_db_handle_t *event_db;
- switch_queue_t *sql_queue[2];
- switch_memory_pool_t *memory_pool;
- switch_event_node_t *event_node;
- switch_thread_t *thread;
- int thread_running;
- switch_bool_t manage;
-} sql_manager;
+ return r;
+}
-static switch_mutex_t *dbh_mutex = NULL;
-static switch_hash_t *dbh_hash = NULL;
#define SQL_CACHE_TIMEOUT 300
int locked = 0;
char *key;
- switch_mutex_lock(dbh_mutex);
+ switch_mutex_lock(sql_manager.dbh_mutex);
top:
locked = 0;
- for (hi = switch_hash_first(NULL, dbh_hash); hi; hi = switch_hash_next(hi)) {
+ for (hi = switch_hash_first(NULL, sql_manager.dbh_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, &var, NULL, &val);
key = (char *) var;
break;
}
- switch_core_hash_delete(dbh_hash, key);
+ switch_core_hash_delete(sql_manager.dbh_hash, key);
switch_mutex_unlock(dbh->mutex);
switch_core_destroy_memory_pool(&dbh->pool);
goto top;
goto top;
}
- switch_mutex_unlock(dbh_mutex);
+ switch_mutex_unlock(sql_manager.dbh_mutex);
}
SWITCH_DECLARE(void) switch_cache_db_destroy_db_handle(switch_cache_db_handle_t **dbh)
{
if (dbh && *dbh) {
- switch_mutex_lock(dbh_mutex);
+ switch_mutex_lock(sql_manager.dbh_mutex);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Deleting DB connection %s\n", (*dbh)->name);
switch ((*dbh)->type) {
}
- switch_core_hash_delete(dbh_hash, (*dbh)->name);
+ switch_core_hash_delete(sql_manager.dbh_hash, (*dbh)->name);
switch_mutex_unlock((*dbh)->mutex);
switch_core_destroy_memory_pool(&(*dbh)->pool);
*dbh = NULL;
- switch_mutex_unlock(dbh_mutex);
+ switch_mutex_unlock(sql_manager.dbh_mutex);
}
}
switch_cache_db_handle_t *dbh = NULL;
snprintf(thread_str, sizeof(thread_str) - 1, "%lu", (unsigned long)(intptr_t)switch_thread_self());
- switch_mutex_lock(dbh_mutex);
+ switch_mutex_lock(sql_manager.dbh_mutex);
- for (hi = switch_hash_first(NULL, dbh_hash); hi; hi = switch_hash_next(hi)) {
+ for (hi = switch_hash_first(NULL, sql_manager.dbh_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, &var, NULL, &val);
key = (char *) var;
if ((dbh = (switch_cache_db_handle_t *) val)) {
}
}
- switch_mutex_unlock(dbh_mutex);
+ switch_mutex_unlock(sql_manager.dbh_mutex);
}
SWITCH_DECLARE(switch_status_t)_switch_cache_db_get_db_handle(switch_cache_db_handle_t **dbh,
snprintf(thread_str, sizeof(thread_str) - 1, "%s;thread=\"%lu\"", db_str, (unsigned long)(intptr_t)self);
snprintf(db_callsite_str, sizeof(db_callsite_str) - 1, "%s:%d", file, line);
- switch_mutex_lock(dbh_mutex);
- if ((new_dbh = switch_core_hash_find(dbh_hash, thread_str))) {
+ switch_mutex_lock(sql_manager.dbh_mutex);
+ if ((new_dbh = switch_core_hash_find(sql_manager.dbh_hash, thread_str))) {
switch_set_string(new_dbh->last_user, db_callsite_str);
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG10,
"Reuse Cached DB handle %s [%s]\n", thread_str, switch_cache_db_type_name(new_dbh->type));
hash = switch_ci_hashfunc_default(db_str, &hlen);
- for (hi = switch_hash_first(NULL, dbh_hash); hi; hi = switch_hash_next(hi)) {
+ for (hi = switch_hash_first(NULL, sql_manager.dbh_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, &var, NULL, &val);
key = (char *) var;
switch_set_string(new_dbh->creator, db_callsite_str);
switch_mutex_lock(new_dbh->mutex);
- switch_core_hash_insert(dbh_hash, new_dbh->name, new_dbh);
+ switch_core_hash_insert(sql_manager.dbh_hash, new_dbh->name, new_dbh);
}
end:
if (new_dbh) new_dbh->last_used = switch_epoch_time_now(NULL);
- switch_mutex_unlock(dbh_mutex);
+ switch_mutex_unlock(sql_manager.dbh_mutex);
*dbh = new_dbh;
switch_status_t status = SWITCH_STATUS_FALSE;
char *errmsg = NULL;
+ if (dbh->io_mutex) {
+ switch_mutex_lock(dbh->io_mutex);
+ }
+
if (err) *err = NULL;
switch (dbh->type) {
free(errmsg);
}
}
+
+
+ if (dbh->io_mutex) {
+ switch_mutex_unlock(dbh->io_mutex);
+ }
return status;
}
{
switch_status_t status = SWITCH_STATUS_FALSE;
+ if (dbh->io_mutex) {
+ switch_mutex_lock(dbh->io_mutex);
+ }
switch (dbh->type) {
default:
break;
}
+ if (dbh->io_mutex) {
+ switch_mutex_unlock(dbh->io_mutex);
+ }
+
return status;
}
switch_status_t status = SWITCH_STATUS_FALSE;
+ if (dbh->io_mutex) {
+ switch_mutex_lock(dbh->io_mutex);
+ }
+
switch (dbh->type) {
case SCDB_TYPE_CORE_DB:
{
end:
+ if (dbh->io_mutex) {
+ switch_mutex_unlock(dbh->io_mutex);
+ }
+
return status == SWITCH_STATUS_SUCCESS ? str : NULL;
}
retries = 1000;
}
+ if (dbh->io_mutex) {
+ switch_mutex_lock(dbh->io_mutex);
+ }
+
while (retries > 0) {
switch_cache_db_execute_sql_real(dbh, sql, &errmsg);
if (errmsg) {
}
}
+ if (dbh->io_mutex) {
+ switch_mutex_unlock(dbh->io_mutex);
+ }
+
return status;
}
retries = 1000;
}
+ if (dbh->io_mutex) {
+ switch_mutex_lock(dbh->io_mutex);
+ }
+
again:
while (begin_retries > 0) {
switch_cache_db_execute_sql_real(dbh, "COMMIT", NULL);
+ if (dbh->io_mutex) {
+ switch_mutex_unlock(dbh->io_mutex);
+ }
+
+
return status;
}
if (err) *err = NULL;
+ if (dbh->io_mutex) {
+ switch_mutex_lock(dbh->io_mutex);
+ }
switch (dbh->type) {
break;
}
+ if (dbh->io_mutex) {
+ switch_mutex_unlock(dbh->io_mutex);
+ }
+
return status;
}
{
char *errmsg;
+
+ if (dbh->io_mutex) {
+ switch_mutex_lock(dbh->io_mutex);
+ }
+
switch (dbh->type) {
case SCDB_TYPE_ODBC:
{
}
break;
}
+
+
+ if (dbh->io_mutex) {
+ switch_mutex_unlock(dbh->io_mutex);
+ }
}
-#define SQLLEN 1024 * 64
+#define SQLLEN 1024 * 1024
static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t * thread, void *obj)
{
void *pop;
uint32_t itterations = 0;
uint8_t trans = 0, nothing_in_queue = 0;
- uint32_t target = 50000;
+ uint32_t target = 100000;
switch_size_t len = 0, sql_len = SQLLEN;
char *tmp, *sqlbuf = (char *) malloc(sql_len);
char *sql;
sql_manager.memory_pool = pool;
sql_manager.manage = manage;
- switch_mutex_init(&dbh_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool);
- switch_core_hash_init(&dbh_hash, sql_manager.memory_pool);
+ switch_mutex_init(&sql_manager.dbh_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool);
+ switch_mutex_init(&sql_manager.io_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool);
+
+ switch_core_hash_init(&sql_manager.dbh_hash, sql_manager.memory_pool);
top:
sql_close(0);
- switch_core_hash_destroy(&dbh_hash);
+ switch_core_hash_destroy(&sql_manager.dbh_hash);
}
char *pos1 = NULL;
char *pos2 = NULL;
- switch_mutex_lock(dbh_mutex);
+ switch_mutex_lock(sql_manager.dbh_mutex);
- for (hi = switch_hash_first(NULL, dbh_hash); hi; hi = switch_hash_next(hi)) {
+ for (hi = switch_hash_first(NULL, sql_manager.dbh_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, &var, NULL, &val);
key = (char *) var;
dbh->last_user);
}
}
- switch_mutex_unlock(dbh_mutex);
+ switch_mutex_unlock(sql_manager.dbh_mutex);
}
/* For Emacs: