FS-3106 --comment-only Try this newer refactored version which completely removes the thread affinity and uses a linked-list to manage the pool, I can run my same 100cps test and only use like 4 db handles
This commit is contained in:
parent
9feab652a3
commit
f542449cac
|
@ -2077,8 +2077,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_preprocess_session(switch_core_sessio
|
|||
#define CACHE_DB_LEN 256
|
||||
typedef enum {
|
||||
CDF_INUSE = (1 << 0),
|
||||
CDF_PRUNE = (1 << 1),
|
||||
CDF_RELEASED = (1 << 2)
|
||||
CDF_PRUNE = (1 << 1)
|
||||
} cache_db_flag_t;
|
||||
|
||||
typedef enum {
|
||||
|
@ -2106,20 +2105,8 @@ typedef union {
|
|||
switch_cache_db_odbc_options_t odbc_options;
|
||||
} switch_cache_db_connection_options_t;
|
||||
|
||||
typedef struct {
|
||||
char name[CACHE_DB_LEN];
|
||||
switch_cache_db_handle_type_t type;
|
||||
switch_cache_db_native_handle_t native_handle;
|
||||
time_t last_used;
|
||||
switch_mutex_t *mutex;
|
||||
switch_mutex_t *io_mutex;
|
||||
switch_memory_pool_t *pool;
|
||||
int32_t flags;
|
||||
unsigned long hash;
|
||||
char creator[CACHE_DB_LEN];
|
||||
char last_user[CACHE_DB_LEN];
|
||||
} switch_cache_db_handle_t;
|
||||
|
||||
struct switch_cache_db_handle;
|
||||
typedef struct switch_cache_db_handle switch_cache_db_handle_t;
|
||||
|
||||
static inline const char *switch_cache_db_type_name(switch_cache_db_handle_type_t type)
|
||||
{
|
||||
|
@ -2141,6 +2128,8 @@ static inline const char *switch_cache_db_type_name(switch_cache_db_handle_type_
|
|||
return type_str;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_cache_db_handle_type_t) switch_cache_db_get_type(switch_cache_db_handle_t *dbh);
|
||||
|
||||
/*!
|
||||
\brief Returns the handle to the pool, immediately available for other
|
||||
threads to use.
|
||||
|
@ -2153,11 +2142,6 @@ SWITCH_DECLARE(void) switch_cache_db_dismiss_db_handle(switch_cache_db_handle_t
|
|||
\param [in] The handle
|
||||
*/
|
||||
SWITCH_DECLARE(void) switch_cache_db_release_db_handle(switch_cache_db_handle_t ** dbh);
|
||||
/*!
|
||||
\brief Removes the handle from the pool and frees up the handle resources.
|
||||
\param [in] The handle
|
||||
*/
|
||||
SWITCH_DECLARE(void) switch_cache_db_destroy_db_handle(switch_cache_db_handle_t ** dbh);
|
||||
/*!
|
||||
\brief Gets a new cached handle from the pool, potentially creating a new connection.
|
||||
The connection is bound to the thread until it (the thread) terminates unless
|
||||
|
@ -2218,10 +2202,7 @@ SWITCH_DECLARE(switch_bool_t) switch_cache_db_test_reactive(switch_cache_db_hand
|
|||
const char *test_sql, const char *drop_sql, const char *reactive_sql);
|
||||
SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute(switch_cache_db_handle_t *dbh, const char *sql, uint32_t retries);
|
||||
SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans(switch_cache_db_handle_t *dbh, char *sql, uint32_t retries);
|
||||
/*!
|
||||
\brief Tries to detach all free connections from current thread.
|
||||
*/
|
||||
SWITCH_DECLARE(void) switch_cache_db_detach(void);
|
||||
|
||||
SWITCH_DECLARE(uint32_t) switch_core_debug_level(void);
|
||||
SWITCH_DECLARE(void) switch_cache_db_flush_handles(void);
|
||||
SWITCH_DECLARE(const char *) switch_core_banner(void);
|
||||
|
|
|
@ -252,7 +252,7 @@ SWITCH_DECLARE(char *) switch_console_expand_alias(char *cmd, char *arg)
|
|||
}
|
||||
|
||||
|
||||
if (db->type == SCDB_TYPE_CORE_DB) {
|
||||
if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) {
|
||||
sql = switch_mprintf("select command from aliases where alias='%q'", cmd);
|
||||
} else {
|
||||
sql = switch_mprintf("select command from aliases where alias='%w'", cmd);
|
||||
|
@ -268,7 +268,7 @@ SWITCH_DECLARE(char *) switch_console_expand_alias(char *cmd, char *arg)
|
|||
switch_safe_free(sql);
|
||||
|
||||
if (!r) {
|
||||
if (db->type == SCDB_TYPE_CORE_DB) {
|
||||
if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) {
|
||||
sql = switch_mprintf("select command from aliases where alias='%q %q'", cmd, arg);
|
||||
} else {
|
||||
sql = switch_mprintf("select command from aliases where alias='%w %w'", cmd, arg);
|
||||
|
@ -794,7 +794,7 @@ SWITCH_DECLARE(unsigned char) switch_console_complete(const char *line, const ch
|
|||
stream.write_function(&stream, "select distinct a1 from complete where " "a1 not in (select name from interfaces where hostname='%s') %s ",
|
||||
switch_core_get_hostname(), argc ? "and" : "");
|
||||
} else {
|
||||
if (db->type == SCDB_TYPE_CORE_DB) {
|
||||
if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) {
|
||||
stream.write_function(&stream, "select distinct a%d,'%q','%q' from complete where ", h.words + 1, switch_str_nil(dup), switch_str_nil(lp));
|
||||
} else {
|
||||
stream.write_function(&stream, "select distinct a%d,'%q','%w' from complete where ", h.words + 1, switch_str_nil(dup), switch_str_nil(lp));
|
||||
|
@ -803,7 +803,7 @@ SWITCH_DECLARE(unsigned char) switch_console_complete(const char *line, const ch
|
|||
|
||||
for (x = 0; x < argc && x < 11; x++) {
|
||||
if (h.words + 1 > argc) {
|
||||
if (db->type == SCDB_TYPE_CORE_DB) {
|
||||
if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) {
|
||||
stream.write_function(&stream, "(a%d like '::%%' or a%d = '' or a%d = '%q')%q",
|
||||
x + 1, x + 1, x + 1, switch_str_nil(argv[x]), x == argc - 1 ? "" : " and ");
|
||||
} else {
|
||||
|
@ -811,7 +811,7 @@ SWITCH_DECLARE(unsigned char) switch_console_complete(const char *line, const ch
|
|||
x + 1, x + 1, x + 1, switch_str_nil(argv[x]), x == argc - 1 ? "" : " and ");
|
||||
}
|
||||
} else {
|
||||
if (db->type == SCDB_TYPE_CORE_DB) {
|
||||
if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) {
|
||||
stream.write_function(&stream, "(a%d like '::%%' or a%d = '' or a%d like '%q%%')%q",
|
||||
x + 1, x + 1, x + 1, switch_str_nil(argv[x]), x == argc - 1 ? "" : " and ");
|
||||
} else {
|
||||
|
@ -1792,7 +1792,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string)
|
|||
if (argv[x + 1] && !strcasecmp(argv[x + 1], "_any_")) {
|
||||
mystream.write_function(&mystream, "%s", "'', ");
|
||||
} else {
|
||||
if (db->type == SCDB_TYPE_CORE_DB) {
|
||||
if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) {
|
||||
mystream.write_function(&mystream, "'%q', ", switch_str_nil(argv[x + 1]));
|
||||
} else {
|
||||
mystream.write_function(&mystream, "'%w', ", switch_str_nil(argv[x + 1]));
|
||||
|
@ -1808,7 +1808,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string)
|
|||
if (argv[x + 1] && !strcasecmp(argv[x + 1], "_any_")) {
|
||||
mystream.write_function(&mystream, "%s", "'', ");
|
||||
} else {
|
||||
if (db->type == SCDB_TYPE_CORE_DB) {
|
||||
if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) {
|
||||
mystream.write_function(&mystream, "'%q', ", switch_str_nil(argv[x + 1]));
|
||||
} else {
|
||||
mystream.write_function(&mystream, "'%w', ", switch_str_nil(argv[x + 1]));
|
||||
|
@ -1826,7 +1826,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string)
|
|||
} else {
|
||||
mystream.write_function(&mystream, "delete from complete where ");
|
||||
for (x = 0; x < argc - 1; x++) {
|
||||
if (db->type == SCDB_TYPE_CORE_DB) {
|
||||
if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) {
|
||||
mystream.write_function(&mystream, "a%d = '%q'%q", x + 1, switch_str_nil(argv[x + 1]), x == argc - 2 ? "" : " and ");
|
||||
} else {
|
||||
mystream.write_function(&mystream, "a%d = '%w'%w", x + 1, switch_str_nil(argv[x + 1]), x == argc - 2 ? "" : " and ");
|
||||
|
@ -1871,7 +1871,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_alias(const char *string)
|
|||
sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_hostname());
|
||||
switch_cache_db_persistant_execute(db, sql, 5);
|
||||
switch_safe_free(sql);
|
||||
if (db->type == SCDB_TYPE_CORE_DB) {
|
||||
if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) {
|
||||
sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (1, '%q','%q','%q')",
|
||||
argv[1], argv[2], switch_core_get_hostname());
|
||||
} else {
|
||||
|
@ -1884,7 +1884,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_alias(const char *string)
|
|||
sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_hostname());
|
||||
switch_cache_db_persistant_execute(db, sql, 5);
|
||||
switch_safe_free(sql);
|
||||
if (db->type == SCDB_TYPE_CORE_DB) {
|
||||
if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) {
|
||||
sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (0, '%q','%q','%q')",
|
||||
argv[1], argv[2], switch_core_get_hostname());
|
||||
} else {
|
||||
|
|
|
@ -409,9 +409,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_new_memory_pool(switch_memor
|
|||
SWITCH_DECLARE(switch_status_t) switch_core_perform_destroy_memory_pool(switch_memory_pool_t **pool, const char *file, const char *func, int line)
|
||||
{
|
||||
switch_assert(pool != NULL);
|
||||
if (switch_core_memory_pool_get_data(*pool, "_in_thread")) {
|
||||
switch_cache_db_detach();
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ALLOC2
|
||||
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Free Pool\n");
|
||||
#endif
|
||||
|
|
|
@ -36,6 +36,21 @@
|
|||
#include "private/switch_core_pvt.h"
|
||||
//*#define DEBUG_SQL 1
|
||||
|
||||
struct switch_cache_db_handle {
|
||||
char name[CACHE_DB_LEN];
|
||||
switch_cache_db_handle_type_t type;
|
||||
switch_cache_db_native_handle_t native_handle;
|
||||
time_t last_used;
|
||||
switch_mutex_t *mutex;
|
||||
switch_mutex_t *io_mutex;
|
||||
switch_memory_pool_t *pool;
|
||||
int32_t flags;
|
||||
unsigned long hash;
|
||||
char creator[CACHE_DB_LEN];
|
||||
char last_user[CACHE_DB_LEN];
|
||||
struct switch_cache_db_handle *next;
|
||||
};
|
||||
|
||||
static struct {
|
||||
switch_cache_db_handle_t *event_db;
|
||||
switch_queue_t *sql_queue[2];
|
||||
|
@ -48,13 +63,74 @@ static struct {
|
|||
switch_bool_t manage;
|
||||
switch_mutex_t *io_mutex;
|
||||
switch_mutex_t *dbh_mutex;
|
||||
switch_hash_t *dbh_hash;
|
||||
switch_cache_db_handle_t *handle_pool;
|
||||
switch_thread_cond_t *cond;
|
||||
switch_mutex_t *cond_mutex;
|
||||
int total_handles;
|
||||
int total_used_handles;
|
||||
} sql_manager;
|
||||
|
||||
|
||||
static void add_handle(switch_cache_db_handle_t *dbh)
|
||||
{
|
||||
switch_mutex_lock(sql_manager.dbh_mutex);
|
||||
dbh->next = sql_manager.handle_pool;
|
||||
sql_manager.handle_pool = dbh;
|
||||
sql_manager.total_handles++;
|
||||
switch_mutex_unlock(sql_manager.dbh_mutex);
|
||||
}
|
||||
|
||||
static void del_handle(switch_cache_db_handle_t *dbh)
|
||||
{
|
||||
switch_cache_db_handle_t *dbhp, *last = NULL;
|
||||
|
||||
switch_mutex_lock(sql_manager.dbh_mutex);
|
||||
for (dbhp = sql_manager.handle_pool; dbhp; dbhp = dbhp->next) {
|
||||
if (dbhp == dbh) {
|
||||
if (last) {
|
||||
last->next = dbhp->next;
|
||||
} else {
|
||||
sql_manager.handle_pool = dbhp->next;
|
||||
}
|
||||
sql_manager.total_handles--;
|
||||
break;
|
||||
}
|
||||
|
||||
last = dbhp;
|
||||
}
|
||||
switch_mutex_unlock(sql_manager.dbh_mutex);
|
||||
}
|
||||
|
||||
static switch_cache_db_handle_t *get_handle(const char *db_str, const char *user_str)
|
||||
{
|
||||
switch_ssize_t hlen = -1;
|
||||
unsigned long hash = 0;
|
||||
switch_cache_db_handle_t *dbhp, *r = NULL;
|
||||
|
||||
|
||||
hash = switch_ci_hashfunc_default(db_str, &hlen);
|
||||
|
||||
switch_mutex_lock(sql_manager.dbh_mutex);
|
||||
for (dbhp = sql_manager.handle_pool; dbhp; dbhp = dbhp->next) {
|
||||
if (dbhp->hash == hash && !switch_test_flag(dbhp, CDF_INUSE) &&
|
||||
!switch_test_flag(dbhp, CDF_PRUNE) && switch_mutex_trylock(dbhp->mutex) == SWITCH_STATUS_SUCCESS) {
|
||||
r = dbhp;
|
||||
|
||||
switch_set_flag(dbhp, CDF_INUSE);
|
||||
sql_manager.total_used_handles++;
|
||||
dbhp->hash = switch_ci_hashfunc_default(db_str, &hlen);
|
||||
switch_set_string(dbhp->last_user, user_str);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch_mutex_unlock(sql_manager.dbh_mutex);
|
||||
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#define SWITCH_CORE_DB "core"
|
||||
/*!
|
||||
\brief Open the default system database
|
||||
|
@ -92,99 +168,58 @@ SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t
|
|||
|
||||
|
||||
#define SQL_CACHE_TIMEOUT 120
|
||||
#define SQL_RELEASE_TIMEOUT 5
|
||||
#define SQL_REG_TIMEOUT 15
|
||||
|
||||
|
||||
static void sql_release(void)
|
||||
{
|
||||
switch_hash_index_t *hi;
|
||||
const void *var;
|
||||
void *val;
|
||||
switch_cache_db_handle_t *dbh = NULL;
|
||||
|
||||
switch_mutex_lock(sql_manager.dbh_mutex);
|
||||
|
||||
for (hi = switch_hash_first(NULL, sql_manager.dbh_hash); hi; hi = switch_hash_next(hi)) {
|
||||
switch_hash_this(hi, &var, NULL, &val);
|
||||
|
||||
if ((dbh = (switch_cache_db_handle_t *) val)) {
|
||||
time_t diff = 0;
|
||||
|
||||
diff = (time_t) switch_epoch_time_now(NULL) - dbh->last_used;
|
||||
|
||||
if (switch_test_flag(dbh, CDF_RELEASED) && diff > SQL_RELEASE_TIMEOUT) {
|
||||
switch_clear_flag(dbh, CDF_INUSE);
|
||||
switch_clear_flag(dbh, CDF_RELEASED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch_mutex_unlock(sql_manager.dbh_mutex);
|
||||
}
|
||||
|
||||
static void sql_close(time_t prune)
|
||||
{
|
||||
switch_hash_index_t *hi;
|
||||
const void *var;
|
||||
void *val;
|
||||
switch_cache_db_handle_t *dbh = NULL;
|
||||
int locked = 0;
|
||||
char *key;
|
||||
|
||||
switch_mutex_lock(sql_manager.dbh_mutex);
|
||||
top:
|
||||
locked = 0;
|
||||
|
||||
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;
|
||||
for (dbh = sql_manager.handle_pool; dbh; dbh = dbh->next) {
|
||||
time_t diff = 0;
|
||||
|
||||
if ((dbh = (switch_cache_db_handle_t *) val)) {
|
||||
time_t diff = 0;
|
||||
|
||||
if (prune > 0 && prune > dbh->last_used) {
|
||||
diff = (time_t) prune - dbh->last_used;
|
||||
}
|
||||
|
||||
if (switch_test_flag(dbh, CDF_RELEASED) && diff > SQL_RELEASE_TIMEOUT) {
|
||||
switch_clear_flag(dbh, CDF_INUSE);
|
||||
switch_clear_flag(dbh, CDF_RELEASED);
|
||||
}
|
||||
|
||||
if (prune > 0 && (switch_test_flag(dbh, CDF_INUSE) || (diff < SQL_CACHE_TIMEOUT && !switch_test_flag(dbh, CDF_PRUNE)))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (switch_mutex_trylock(dbh->mutex) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Dropping idle DB connection %s\n", key);
|
||||
|
||||
switch (dbh->type) {
|
||||
case SCDB_TYPE_ODBC:
|
||||
{
|
||||
switch_odbc_handle_destroy(&dbh->native_handle.odbc_dbh);
|
||||
}
|
||||
break;
|
||||
case SCDB_TYPE_CORE_DB:
|
||||
{
|
||||
switch_core_db_close(dbh->native_handle.core_db_dbh);
|
||||
dbh->native_handle.core_db_dbh = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch_core_hash_delete(sql_manager.dbh_hash, key);
|
||||
sql_manager.total_handles--;
|
||||
switch_mutex_unlock(dbh->mutex);
|
||||
switch_core_destroy_memory_pool(&dbh->pool);
|
||||
goto top;
|
||||
|
||||
} else {
|
||||
if (!prune)
|
||||
locked++;
|
||||
continue;
|
||||
}
|
||||
if (prune > 0 && prune > dbh->last_used) {
|
||||
diff = (time_t) prune - dbh->last_used;
|
||||
}
|
||||
|
||||
if (prune > 0 && (switch_test_flag(dbh, CDF_INUSE) || (diff < SQL_CACHE_TIMEOUT && !switch_test_flag(dbh, CDF_PRUNE)))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (switch_mutex_trylock(dbh->mutex) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Dropping idle DB connection %s\n", dbh->name);
|
||||
|
||||
switch (dbh->type) {
|
||||
case SCDB_TYPE_ODBC:
|
||||
{
|
||||
switch_odbc_handle_destroy(&dbh->native_handle.odbc_dbh);
|
||||
}
|
||||
break;
|
||||
case SCDB_TYPE_CORE_DB:
|
||||
{
|
||||
switch_core_db_close(dbh->native_handle.core_db_dbh);
|
||||
dbh->native_handle.core_db_dbh = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
del_handle(dbh);
|
||||
switch_mutex_unlock(dbh->mutex);
|
||||
switch_core_destroy_memory_pool(&dbh->pool);
|
||||
goto top;
|
||||
|
||||
} else {
|
||||
if (!prune) {
|
||||
locked++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (locked) {
|
||||
|
@ -195,6 +230,11 @@ static void sql_close(time_t prune)
|
|||
}
|
||||
|
||||
|
||||
SWITCH_DECLARE(switch_cache_db_handle_type_t) switch_cache_db_get_type(switch_cache_db_handle_t *dbh)
|
||||
{
|
||||
return dbh->type;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(void) switch_cache_db_flush_handles(void)
|
||||
{
|
||||
sql_close(switch_epoch_time_now(NULL) + SQL_CACHE_TIMEOUT + 1);
|
||||
|
@ -204,10 +244,13 @@ SWITCH_DECLARE(void) switch_cache_db_flush_handles(void)
|
|||
SWITCH_DECLARE(void) switch_cache_db_release_db_handle(switch_cache_db_handle_t **dbh)
|
||||
{
|
||||
if (dbh && *dbh) {
|
||||
switch_set_flag((*dbh), CDF_RELEASED);
|
||||
switch_mutex_lock(sql_manager.dbh_mutex);
|
||||
(*dbh)->last_used = switch_epoch_time_now(NULL);
|
||||
switch_clear_flag((*dbh), CDF_INUSE);
|
||||
switch_mutex_unlock((*dbh)->mutex);
|
||||
sql_manager.total_used_handles--;
|
||||
*dbh = NULL;
|
||||
switch_mutex_unlock(sql_manager.dbh_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,83 +261,15 @@ SWITCH_DECLARE(void) switch_cache_db_dismiss_db_handle(switch_cache_db_handle_t
|
|||
}
|
||||
|
||||
|
||||
SWITCH_DECLARE(void) switch_cache_db_destroy_db_handle(switch_cache_db_handle_t **dbh)
|
||||
{
|
||||
if (dbh && *dbh) {
|
||||
switch_mutex_lock(sql_manager.dbh_mutex);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Deleting DB connection %s\n", (*dbh)->name);
|
||||
|
||||
switch ((*dbh)->type) {
|
||||
case SCDB_TYPE_ODBC:
|
||||
{
|
||||
switch_odbc_handle_destroy(&(*dbh)->native_handle.odbc_dbh);
|
||||
}
|
||||
break;
|
||||
case SCDB_TYPE_CORE_DB:
|
||||
{
|
||||
switch_core_db_close((*dbh)->native_handle.core_db_dbh);
|
||||
(*dbh)->native_handle.core_db_dbh = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
switch_core_hash_delete(sql_manager.dbh_hash, (*dbh)->name);
|
||||
sql_manager.total_handles--;
|
||||
switch_mutex_unlock((*dbh)->mutex);
|
||||
switch_core_destroy_memory_pool(&(*dbh)->pool);
|
||||
*dbh = NULL;
|
||||
switch_mutex_unlock(sql_manager.dbh_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(void) switch_cache_db_detach(void)
|
||||
{
|
||||
char thread_str[CACHE_DB_LEN] = "";
|
||||
switch_hash_index_t *hi;
|
||||
const void *var;
|
||||
void *val;
|
||||
char *key;
|
||||
switch_cache_db_handle_t *dbh = NULL;
|
||||
|
||||
if (!sql_manager.dbh_hash) {
|
||||
return;
|
||||
}
|
||||
snprintf(thread_str, sizeof(thread_str) - 1, "%lu", (unsigned long) (intptr_t) switch_thread_self());
|
||||
switch_mutex_lock(sql_manager.dbh_mutex);
|
||||
|
||||
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)) {
|
||||
if (switch_mutex_trylock(dbh->mutex) == SWITCH_STATUS_SUCCESS) {
|
||||
if (strstr(dbh->name, thread_str)) {
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10,
|
||||
"Detach cached DB handle %s [%s]\n", thread_str, switch_cache_db_type_name(dbh->type));
|
||||
switch_set_flag(dbh, CDF_RELEASED);
|
||||
|
||||
}
|
||||
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,
|
||||
switch_cache_db_handle_type_t type,
|
||||
switch_cache_db_connection_options_t *connection_options,
|
||||
const char *file, const char *func, int line)
|
||||
{
|
||||
switch_thread_id_t self = switch_thread_self();
|
||||
char thread_str[CACHE_DB_LEN] = "";
|
||||
char db_str[CACHE_DB_LEN] = "";
|
||||
char db_callsite_str[CACHE_DB_LEN] = "";
|
||||
switch_cache_db_handle_t *new_dbh = NULL;
|
||||
switch_ssize_t hlen = -1;
|
||||
int locked = 0;
|
||||
|
||||
const char *db_name = NULL;
|
||||
const char *db_user = NULL;
|
||||
|
@ -322,57 +297,14 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h
|
|||
}
|
||||
|
||||
snprintf(db_str, sizeof(db_str) - 1, "db=\"%s\";user=\"%s\";pass=\"%s\"", db_name, db_user, db_pass);
|
||||
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(sql_manager.dbh_mutex);
|
||||
|
||||
if ((new_dbh = switch_core_hash_find(sql_manager.dbh_hash, thread_str))) {
|
||||
if ((switch_test_flag(new_dbh, CDF_INUSE) && !switch_test_flag(new_dbh, CDF_RELEASED)) ||
|
||||
switch_test_flag(new_dbh, CDF_PRUNE) || switch_mutex_trylock(new_dbh->mutex) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG10,
|
||||
"Cached DB handle %s already in use. [%s]\n", new_dbh->name, switch_cache_db_type_name(new_dbh->type));
|
||||
new_dbh = NULL;
|
||||
} else {
|
||||
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", new_dbh->name, switch_cache_db_type_name(new_dbh->type));
|
||||
locked = 1;
|
||||
switch_clear_flag(new_dbh, CDF_RELEASED);
|
||||
}
|
||||
}
|
||||
|
||||
if (!new_dbh) {
|
||||
switch_hash_index_t *hi;
|
||||
const void *var;
|
||||
void *val;
|
||||
char *key;
|
||||
unsigned long hash = 0;
|
||||
|
||||
hash = switch_ci_hashfunc_default(db_str, &hlen);
|
||||
|
||||
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 ((new_dbh = (switch_cache_db_handle_t *) val)) {
|
||||
if (hash == new_dbh->hash && !strncasecmp(new_dbh->name, db_str, strlen(db_str)) &&
|
||||
!switch_test_flag(new_dbh, CDF_INUSE) && !switch_test_flag(new_dbh, CDF_PRUNE)
|
||||
&& switch_mutex_trylock(new_dbh->mutex) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_set_flag(new_dbh, CDF_INUSE);
|
||||
switch_set_string(new_dbh->name, thread_str);
|
||||
new_dbh->hash = switch_ci_hashfunc_default(db_str, &hlen);
|
||||
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 Unused Cached DB handle %s [%s]\n", new_dbh->name, switch_cache_db_type_name(new_dbh->type));
|
||||
break;
|
||||
}
|
||||
}
|
||||
new_dbh = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!new_dbh) {
|
||||
if ((new_dbh = get_handle(db_str, db_callsite_str))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG10,
|
||||
"Reuse Unused Cached DB handle %s [%s]\n", new_dbh->name, switch_cache_db_type_name(new_dbh->type));
|
||||
} else {
|
||||
switch_memory_pool_t *pool = NULL;
|
||||
switch_core_db_t *db = NULL;
|
||||
switch_odbc_handle_t *odbc_dbh = NULL;
|
||||
|
@ -412,7 +344,7 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h
|
|||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG10,
|
||||
"Create Cached DB handle %s [%s] %s:%d\n", thread_str, switch_cache_db_type_name(type), file, line);
|
||||
"Create Cached DB handle %s [%s] %s:%d\n", new_dbh->name, switch_cache_db_type_name(type), file, line);
|
||||
|
||||
switch_core_new_memory_pool(&pool);
|
||||
new_dbh = switch_core_alloc(pool, sizeof(*new_dbh));
|
||||
|
@ -420,8 +352,9 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h
|
|||
new_dbh->type = type;
|
||||
|
||||
|
||||
switch_set_string(new_dbh->name, thread_str);
|
||||
switch_set_string(new_dbh->name, db_str);
|
||||
switch_set_flag(new_dbh, CDF_INUSE);
|
||||
sql_manager.total_used_handles++;
|
||||
new_dbh->hash = switch_ci_hashfunc_default(db_str, &hlen);
|
||||
|
||||
|
||||
|
@ -433,10 +366,8 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h
|
|||
|
||||
switch_mutex_init(&new_dbh->mutex, SWITCH_MUTEX_UNNESTED, new_dbh->pool);
|
||||
switch_set_string(new_dbh->creator, db_callsite_str);
|
||||
if (!locked) switch_mutex_lock(new_dbh->mutex);
|
||||
|
||||
switch_core_hash_insert(sql_manager.dbh_hash, new_dbh->name, new_dbh);
|
||||
sql_manager.total_handles++;
|
||||
switch_mutex_lock(new_dbh->mutex);
|
||||
add_handle(new_dbh);
|
||||
}
|
||||
|
||||
end:
|
||||
|
@ -926,14 +857,7 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_db_thread(switch_thread_t *threa
|
|||
sql_manager.db_thread_running = 1;
|
||||
|
||||
while (sql_manager.db_thread_running == 1) {
|
||||
sec++;
|
||||
|
||||
if ((sec % SQL_RELEASE_TIMEOUT) == 0 || sec == 1) {
|
||||
sql_release();
|
||||
wake_thread(0);
|
||||
}
|
||||
|
||||
if (sec == SQL_CACHE_TIMEOUT) {
|
||||
if (++sec == SQL_CACHE_TIMEOUT) {
|
||||
sql_close(switch_epoch_time_now(NULL));
|
||||
wake_thread(0);
|
||||
sec = 0;
|
||||
|
@ -1783,8 +1707,6 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_
|
|||
|
||||
switch_thread_cond_create(&sql_manager.cond, sql_manager.memory_pool);
|
||||
|
||||
switch_core_hash_init(&sql_manager.dbh_hash, sql_manager.memory_pool);
|
||||
|
||||
top:
|
||||
|
||||
if (!sql_manager.manage) goto skip;
|
||||
|
@ -1966,65 +1888,57 @@ void switch_core_sqldb_stop(void)
|
|||
|
||||
switch_cache_db_flush_handles();
|
||||
sql_close(0);
|
||||
|
||||
switch_core_hash_destroy(&sql_manager.dbh_hash);
|
||||
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(void) switch_cache_db_status(switch_stream_handle_t *stream)
|
||||
{
|
||||
/* return some status info suitable for the cli */
|
||||
switch_hash_index_t *hi;
|
||||
switch_cache_db_handle_t *dbh = NULL;
|
||||
void *val;
|
||||
const void *var;
|
||||
char *key;
|
||||
switch_bool_t locked = SWITCH_FALSE;
|
||||
time_t now = switch_epoch_time_now(NULL);
|
||||
char cleankey_str[CACHE_DB_LEN];
|
||||
char *pos1 = NULL;
|
||||
char *pos2 = NULL;
|
||||
int count = 0;
|
||||
int count = 0, used = 0;
|
||||
|
||||
switch_mutex_lock(sql_manager.dbh_mutex);
|
||||
|
||||
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;
|
||||
for (dbh = sql_manager.handle_pool; dbh; dbh = dbh->next) {
|
||||
char *needle = "pass=\"";
|
||||
time_t diff = 0;
|
||||
|
||||
if ((dbh = (switch_cache_db_handle_t *) val)) {
|
||||
char *needle = "pass=\"";
|
||||
time_t diff = 0;
|
||||
diff = now - dbh->last_used;
|
||||
|
||||
diff = now - dbh->last_used;
|
||||
|
||||
if (switch_mutex_trylock(dbh->mutex) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_mutex_unlock(dbh->mutex);
|
||||
locked = SWITCH_FALSE;
|
||||
} else {
|
||||
locked = SWITCH_TRUE;
|
||||
}
|
||||
|
||||
/* sanitize password */
|
||||
memset(cleankey_str, 0, sizeof(cleankey_str));
|
||||
pos1 = strstr(key, needle) + strlen(needle);
|
||||
pos2 = strstr(pos1, "\"");
|
||||
strncpy(cleankey_str, key, pos1 - key);
|
||||
strcpy(&cleankey_str[pos1 - key], pos2);
|
||||
|
||||
count++;
|
||||
stream->write_function(stream, "%s\n\tType: %s\n\tLast used: %d\n\tFlags: %s, %s\n"
|
||||
"\tCreator: %s\n\tLast User: %s\n",
|
||||
cleankey_str,
|
||||
switch_cache_db_type_name(dbh->type),
|
||||
diff,
|
||||
locked ? "Locked" : "Unlocked",
|
||||
switch_test_flag(dbh, CDF_INUSE) ? switch_test_flag(dbh, CDF_RELEASED) ? "Released" :
|
||||
"Attached" : "Detached", dbh->creator, dbh->last_user);
|
||||
if (switch_mutex_trylock(dbh->mutex) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_mutex_unlock(dbh->mutex);
|
||||
locked = SWITCH_FALSE;
|
||||
} else {
|
||||
locked = SWITCH_TRUE;
|
||||
}
|
||||
|
||||
/* sanitize password */
|
||||
memset(cleankey_str, 0, sizeof(cleankey_str));
|
||||
pos1 = strstr(dbh->name, needle) + strlen(needle);
|
||||
pos2 = strstr(pos1, "\"");
|
||||
strncpy(cleankey_str, dbh->name, pos1 - dbh->name);
|
||||
strcpy(&cleankey_str[pos1 - dbh->name], pos2);
|
||||
|
||||
count++;
|
||||
|
||||
if (switch_test_flag(dbh, CDF_INUSE)) {
|
||||
used++;
|
||||
}
|
||||
|
||||
stream->write_function(stream, "%s\n\tType: %s\n\tLast used: %d\n\tFlags: %s, %s\n"
|
||||
"\tCreator: %s\n\tLast User: %s\n",
|
||||
cleankey_str,
|
||||
switch_cache_db_type_name(dbh->type),
|
||||
diff,
|
||||
locked ? "Locked" : "Unlocked",
|
||||
switch_test_flag(dbh, CDF_INUSE) ? "Attached" : "Detached", dbh->creator, dbh->last_user);
|
||||
}
|
||||
|
||||
stream->write_function(stream, "%d total\n", count);
|
||||
stream->write_function(stream, "%d total. %d in use.\n", count, used);
|
||||
|
||||
switch_mutex_unlock(sql_manager.dbh_mutex);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue