Skip to content
Snippets Groups Projects
Commit 6181e386 authored by Tilghman Lesher's avatar Tilghman Lesher
Browse files

Merged revisions 99341 via svnmerge from

https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r99341 | tilghman | 2008-01-21 12:11:07 -0600 (Mon, 21 Jan 2008) | 8 lines

Permit the user to specify number of seconds that a connection may remain idle,
which fixes a crash on reconnect with the MyODBC driver.
(closes issue #11798)
 Reported by: Corydon76
 Patches: 
       20080119__res_odbc__idlecheck.diff.txt uploaded by Corydon76 (license 14)
 Tested by: mvanbaak

........


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@99350 65c4cc65-6c06-0410-ace0-fbb531ad65f3
parent 965c4545
Branches
Tags
No related merge requests found
...@@ -27,6 +27,11 @@ dsn => MySQL-asterisk ...@@ -27,6 +27,11 @@ dsn => MySQL-asterisk
username => myuser username => myuser
password => mypass password => mypass
pre-connect => yes pre-connect => yes
;
; On some databases, the connection times out and a reconnection will be
; necessary. This setting configures the amount of time a connection
; may sit idle (in seconds) before a reconnection will be attempted.
;idlecheck => 3600
; Certain servers, such as MS SQL Server and Sybase use the TDS protocol, which ; Certain servers, such as MS SQL Server and Sybase use the TDS protocol, which
; limits the number of active queries per connection to 1. By setting up pools ; limits the number of active queries per connection to 1. By setting up pools
......
...@@ -38,6 +38,7 @@ struct odbc_obj { ...@@ -38,6 +38,7 @@ struct odbc_obj {
ast_mutex_t lock; ast_mutex_t lock;
SQLHDBC con; /* ODBC Connection Handle */ SQLHDBC con; /* ODBC Connection Handle */
struct odbc_class *parent; /* Information about the connection is protected */ struct odbc_class *parent; /* Information about the connection is protected */
struct timeval last_used;
unsigned int used:1; unsigned int used:1;
unsigned int up:1; unsigned int up:1;
AST_LIST_ENTRY(odbc_obj) list; AST_LIST_ENTRY(odbc_obj) list;
......
...@@ -46,6 +46,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") ...@@ -46,6 +46,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/cli.h" #include "asterisk/cli.h"
#include "asterisk/lock.h" #include "asterisk/lock.h"
#include "asterisk/res_odbc.h" #include "asterisk/res_odbc.h"
#include "asterisk/time.h"
struct odbc_class struct odbc_class
{ {
...@@ -61,6 +62,7 @@ struct odbc_class ...@@ -61,6 +62,7 @@ struct odbc_class
unsigned int count:10; /* Running count of pooled connections */ unsigned int count:10; /* Running count of pooled connections */
unsigned int delme:1; /* Purge the class */ unsigned int delme:1; /* Purge the class */
unsigned int backslash_is_escape:1; /* On this database, the backslash is a native escape sequence */ unsigned int backslash_is_escape:1; /* On this database, the backslash is a native escape sequence */
unsigned int idlecheck; /* Recheck the connection if it is idle for this long */
AST_LIST_HEAD(, odbc_obj) odbc_obj; AST_LIST_HEAD(, odbc_obj) odbc_obj;
}; };
...@@ -135,7 +137,8 @@ SQLHSTMT ast_odbc_prepare_and_execute(struct odbc_obj *obj, SQLHSTMT (*prepare_c ...@@ -135,7 +137,8 @@ SQLHSTMT ast_odbc_prepare_and_execute(struct odbc_obj *obj, SQLHSTMT (*prepare_c
*/ */
ast_odbc_sanity_check(obj); ast_odbc_sanity_check(obj);
continue; continue;
} } else
obj->last_used = ast_tvnow();
break; break;
} else if (attempt == 0) } else if (attempt == 0)
ast_odbc_sanity_check(obj); ast_odbc_sanity_check(obj);
...@@ -180,7 +183,8 @@ int ast_odbc_smart_execute(struct odbc_obj *obj, SQLHSTMT stmt) ...@@ -180,7 +183,8 @@ int ast_odbc_smart_execute(struct odbc_obj *obj, SQLHSTMT stmt)
odbc_obj_connect(obj); odbc_obj_connect(obj);
res = SQLExecute(stmt); res = SQLExecute(stmt);
#endif #endif
} } else
obj->last_used = ast_tvnow();
return res; return res;
} }
...@@ -229,6 +233,7 @@ static int load_odbc_config(void) ...@@ -229,6 +233,7 @@ static int load_odbc_config(void)
char *cat; char *cat;
const char *dsn, *username, *password, *sanitysql; const char *dsn, *username, *password, *sanitysql;
int enabled, pooling, limit, bse; int enabled, pooling, limit, bse;
unsigned int idlecheck;
int connect = 0, res = 0; int connect = 0, res = 0;
struct ast_flags config_flags = { 0 }; struct ast_flags config_flags = { 0 };
...@@ -249,7 +254,7 @@ static int load_odbc_config(void) ...@@ -249,7 +254,7 @@ static int load_odbc_config(void)
/* Reset all to defaults for each class of odbc connections */ /* Reset all to defaults for each class of odbc connections */
dsn = username = password = sanitysql = NULL; dsn = username = password = sanitysql = NULL;
enabled = 1; enabled = 1;
connect = 0; connect = idlecheck = 0;
pooling = 0; pooling = 0;
limit = 0; limit = 0;
bse = 1; bse = 1;
...@@ -267,6 +272,8 @@ static int load_odbc_config(void) ...@@ -267,6 +272,8 @@ static int load_odbc_config(void)
enabled = 0; enabled = 0;
break; break;
} }
} else if (!strcasecmp(v->name, "idlecheck")) {
sscanf(v->value, "%d", &idlecheck);
} else if (!strcasecmp(v->name, "enabled")) { } else if (!strcasecmp(v->name, "enabled")) {
enabled = ast_true(v->value); enabled = ast_true(v->value);
} else if (!strcasecmp(v->name, "pre-connect")) { } else if (!strcasecmp(v->name, "pre-connect")) {
...@@ -323,6 +330,7 @@ static int load_odbc_config(void) ...@@ -323,6 +330,7 @@ static int load_odbc_config(void)
} }
new->backslash_is_escape = bse ? 1 : 0; new->backslash_is_escape = bse ? 1 : 0;
new->idlecheck = idlecheck;
odbc_register_class(new, connect); odbc_register_class(new, connect);
ast_log(LOG_NOTICE, "Registered ODBC class '%s' dsn->[%s]\n", cat, dsn); ast_log(LOG_NOTICE, "Registered ODBC class '%s' dsn->[%s]\n", cat, dsn);
...@@ -508,7 +516,9 @@ struct odbc_obj *ast_odbc_request_obj(const char *name, int check) ...@@ -508,7 +516,9 @@ struct odbc_obj *ast_odbc_request_obj(const char *name, int check)
if (obj && check) { if (obj && check) {
ast_odbc_sanity_check(obj); ast_odbc_sanity_check(obj);
} } else if (obj->parent->idlecheck > 0 && ast_tvdiff_ms(ast_tvnow(), obj->last_used) / 1000 > obj->parent->idlecheck)
odbc_obj_connect(obj);
return obj; return obj;
} }
...@@ -576,6 +586,7 @@ static odbc_status odbc_obj_connect(struct odbc_obj *obj) ...@@ -576,6 +586,7 @@ static odbc_status odbc_obj_connect(struct odbc_obj *obj)
} else { } else {
ast_log(LOG_NOTICE, "res_odbc: Connected to %s [%s]\n", obj->parent->name, obj->parent->dsn); ast_log(LOG_NOTICE, "res_odbc: Connected to %s [%s]\n", obj->parent->name, obj->parent->dsn);
obj->up = 1; obj->up = 1;
obj->last_used = ast_tvnow();
} }
ast_mutex_unlock(&obj->lock); ast_mutex_unlock(&obj->lock);
...@@ -590,6 +601,7 @@ static int reload(void) ...@@ -590,6 +601,7 @@ static int reload(void)
char *cat; char *cat;
const char *dsn, *username, *password, *sanitysql; const char *dsn, *username, *password, *sanitysql;
int enabled, pooling, limit, bse; int enabled, pooling, limit, bse;
unsigned int idlecheck;
int connect = 0, res = 0; int connect = 0, res = 0;
struct ast_flags config_flags = { CONFIG_FLAG_FILEUNCHANGED }; struct ast_flags config_flags = { CONFIG_FLAG_FILEUNCHANGED };
...@@ -615,7 +627,7 @@ static int reload(void) ...@@ -615,7 +627,7 @@ static int reload(void)
/* Reset all to defaults for each class of odbc connections */ /* Reset all to defaults for each class of odbc connections */
dsn = username = password = sanitysql = NULL; dsn = username = password = sanitysql = NULL;
enabled = 1; enabled = 1;
connect = 0; connect = idlecheck = 0;
pooling = 0; pooling = 0;
limit = 0; limit = 0;
bse = 1; bse = 1;
...@@ -632,6 +644,8 @@ static int reload(void) ...@@ -632,6 +644,8 @@ static int reload(void)
enabled = 0; enabled = 0;
break; break;
} }
} else if (!strcasecmp(v->name, "idlecheck")) {
sscanf(v->value, "%ud", &idlecheck);
} else if (!strcasecmp(v->name, "enabled")) { } else if (!strcasecmp(v->name, "enabled")) {
enabled = ast_true(v->value); enabled = ast_true(v->value);
} else if (!strcasecmp(v->name, "pre-connect")) { } else if (!strcasecmp(v->name, "pre-connect")) {
...@@ -720,6 +734,7 @@ static int reload(void) ...@@ -720,6 +734,7 @@ static int reload(void)
} }
new->backslash_is_escape = bse; new->backslash_is_escape = bse;
new->idlecheck = idlecheck;
if (class) { if (class) {
ast_log(LOG_NOTICE, "Refreshing ODBC class '%s' dsn->[%s]\n", cat, dsn); ast_log(LOG_NOTICE, "Refreshing ODBC class '%s' dsn->[%s]\n", cat, dsn);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment