summaryrefslogtreecommitdiff
path: root/funcs
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2012-01-24 17:04:20 +0000
committerRichard Mudgett <rmudgett@digium.com>2012-01-24 17:04:20 +0000
commit2144ba5df2813609024964c4c2d9060b30d5cd43 (patch)
tree4a9b5856e9f988a9fbdc5bdde610c146aaf5a841 /funcs
parent84aea92ba7b71ff17aa9c1d3ed05345d3fb570c0 (diff)
Fix locking issues with channel datastores in func_odbc.c.
* Fixed a potential memory leak when an existing datastore is manually destroyed by inline code instead of calling ast_datastore_free(). (closes issue ASTERISK-17948) Reported by: Archie Cobbs Review: https://reviewboard.asterisk.org/r/1687/ ........ Merged revisions 352291 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 352292 from http://svn.asterisk.org/svn/asterisk/branches/10 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@352293 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'funcs')
-rw-r--r--funcs/func_odbc.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/funcs/func_odbc.c b/funcs/func_odbc.c
index eeb7d3be1..edb69f093 100644
--- a/funcs/func_odbc.c
+++ b/funcs/func_odbc.c
@@ -727,8 +727,7 @@ end_acf_read:
ast_channel_lock(chan);
if ((odbc_store = ast_channel_datastore_find(chan, &odbc_info, buf))) {
ast_channel_datastore_remove(chan, odbc_store);
- odbc_datastore_free(odbc_store->data);
- ast_free(odbc_store);
+ ast_datastore_free(odbc_store);
}
ast_channel_unlock(chan);
}
@@ -745,7 +744,9 @@ end_acf_read:
return -1;
}
odbc_store->data = resultset;
+ ast_channel_lock(chan);
ast_channel_datastore_add(chan, odbc_store);
+ ast_channel_unlock(chan);
}
}
SQLCloseCursor(stmt);
@@ -791,8 +792,11 @@ static int acf_fetch(struct ast_channel *chan, const char *cmd, char *data, char
struct ast_datastore *store;
struct odbc_datastore *resultset;
struct odbc_datastore_row *row;
+
+ ast_channel_lock(chan);
store = ast_channel_datastore_find(chan, &odbc_info, data);
if (!store) {
+ ast_channel_unlock(chan);
pbx_builtin_setvar_helper(chan, "ODBC_FETCH_STATUS", "FAILURE");
return -1;
}
@@ -804,10 +808,12 @@ static int acf_fetch(struct ast_channel *chan, const char *cmd, char *data, char
/* Cleanup datastore */
ast_channel_datastore_remove(chan, store);
ast_datastore_free(store);
+ ast_channel_unlock(chan);
pbx_builtin_setvar_helper(chan, "ODBC_FETCH_STATUS", "FAILURE");
return -1;
}
pbx_builtin_setvar_helper(chan, "~ODBCFIELDS~", resultset->names);
+ ast_channel_unlock(chan);
ast_copy_string(buf, row->data, len);
ast_free(row);
pbx_builtin_setvar_helper(chan, "ODBC_FETCH_STATUS", "SUCCESS");
@@ -824,11 +830,15 @@ static char *app_odbcfinish = "ODBCFinish";
static int exec_odbcfinish(struct ast_channel *chan, const char *data)
{
- struct ast_datastore *store = ast_channel_datastore_find(chan, &odbc_info, data);
- if (!store) /* Already freed; no big deal. */
- return 0;
- ast_channel_datastore_remove(chan, store);
- ast_datastore_free(store);
+ struct ast_datastore *store;
+
+ ast_channel_lock(chan);
+ store = ast_channel_datastore_find(chan, &odbc_info, data);
+ if (store) {
+ ast_channel_datastore_remove(chan, store);
+ ast_datastore_free(store);
+ }
+ ast_channel_unlock(chan);
return 0;
}