func_odbc: Fix connection deadlock.

The func_odbc module was modified to ensure that the
previous behavior of using a single database connection
was maintained. This was done by getting a single database
connection and holding on to it. With the new multiple
connection support in res_odbc this will actually starve
every other thread from getting access to the database as
it also maintains the previous behavior of having only
a single database connection.

This change disables the func_odbc specific behavior if
the res_odbc module is running with only a single database
connection active. The connection is only kept for the
duration of the request.

ASTERISK-26177 #close

Change-Id: I9bdbd8a300fb3233877735ad3fd07bce38115b7f
This commit is contained in:
Joshua Colp
2016-07-10 21:08:28 -03:00
parent 44f16af7cc
commit 4ad333bb0e
3 changed files with 37 additions and 0 deletions

View File

@@ -388,9 +388,25 @@ static struct odbc_obj *get_odbc_obj(const char *dsn_name, struct dsn **dsn)
static inline void release_obj_or_dsn(struct odbc_obj **obj, struct dsn **dsn)
{
if (dsn && *dsn) {
/* If multiple connections are not enabled then the guarantee
* of a single connection already exists and holding on to the
* connection would prevent any other user from acquiring it
* indefinitely.
*/
if (ast_odbc_get_max_connections((*dsn)->name) < 2) {
ast_odbc_release_obj((*dsn)->connection);
(*dsn)->connection = NULL;
}
ao2_unlock(*dsn);
ao2_ref(*dsn, -1);
*dsn = NULL;
/* Some callers may provide both an obj and dsn. To ensure that
* the connection is not released twice we set it to NULL here if
* present.
*/
if (obj) {
*obj = NULL;
}
} else if (obj && *obj) {
ast_odbc_release_obj(*obj);
*obj = NULL;