[asterisk-commits] rmudgett: trunk r352293 - in /trunk: ./ funcs/func_odbc.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jan 24 11:04:26 CST 2012


Author: rmudgett
Date: Tue Jan 24 11:04:20 2012
New Revision: 352293

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=352293
Log:
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

Modified:
    trunk/   (props changed)
    trunk/funcs/func_odbc.c

Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-10-merged' - no diff available.

Modified: trunk/funcs/func_odbc.c
URL: http://svnview.digium.com/svn/asterisk/trunk/funcs/func_odbc.c?view=diff&rev=352293&r1=352292&r2=352293
==============================================================================
--- trunk/funcs/func_odbc.c (original)
+++ trunk/funcs/func_odbc.c Tue Jan 24 11:04:20 2012
@@ -727,8 +727,7 @@
 				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 @@
 				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 @@
 	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 @@
 		/* 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 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;
 }
 




More information about the asterisk-commits mailing list