[asterisk-addons-commits] tilghman: trunk r960 - in /trunk: ./ apps/ configs/

SVN commits to the Asterisk addons project asterisk-addons-commits at lists.digium.com
Mon Jun 29 17:33:34 CDT 2009


Author: tilghman
Date: Mon Jun 29 17:33:29 2009
New Revision: 960

URL: http://svn.asterisk.org/svn-view/asterisk-addons?view=rev&rev=960
Log:
Merged revisions 959 via svnmerge from 
https://origsvn.digium.com/svn/asterisk-addons/branches/1.4

........
  r959 | tilghman | 2009-06-29 17:21:09 -0500 (Mon, 29 Jun 2009) | 8 lines
  
  Autoclear resources in app MYSQL when the channel ends.
  (closes issue #14757)
   Reported by: alecdavis
   Patches: 
         20090408__bug14757.diff.txt uploaded by tilghman (license 14)
         20090518__issue14757__trunk.diff.txt uploaded by tilghman (license 14)
   Tested by: alecdavis
........

Modified:
    trunk/   (props changed)
    trunk/apps/app_addon_sql_mysql.c
    trunk/configs/mysql.conf.sample

Propchange: trunk/
------------------------------------------------------------------------------
--- branch-1.4-merged (original)
+++ branch-1.4-merged Mon Jun 29 17:33:29 2009
@@ -1,1 +1,1 @@
-/branches/1.4:1-299,308,310,317,319,329,342,348,358,380,382,387,389,398,405,410,414,417,423,428,466,472,475,479,485,490,502,539,574,578,606,714,886,932
+/branches/1.4:1-299,308,310,317,319,329,342,348,358,380,382,387,389,398,405,410,414,417,423,428,466,472,475,479,485,490,502,539,574,578,606,714,886,932,959

Modified: trunk/apps/app_addon_sql_mysql.c
URL: http://svn.asterisk.org/svn-view/asterisk-addons/trunk/apps/app_addon_sql_mysql.c?view=diff&rev=960&r1=959&r2=960
==============================================================================
--- trunk/apps/app_addon_sql_mysql.c (original)
+++ trunk/apps/app_addon_sql_mysql.c Mon Jun 29 17:33:29 2009
@@ -94,7 +94,19 @@
 #define AST_MYSQL_ID_RESID   2
 #define AST_MYSQL_ID_FETCHID 3
 
+int autoclear = 0;
+
+static void mysql_ds_destroy(void *data);
+static void mysql_ds_fixup(void *data, struct ast_channel *oldchan, struct ast_channel *newchan);
+
+static struct ast_datastore_info mysql_ds_info = {
+	.type = "APP_ADDON_SQL_MYSQL",
+	.destroy = mysql_ds_destroy,
+	.chan_fixup = mysql_ds_fixup,
+};
+
 struct ast_MYSQL_id {
+	struct ast_channel *owner;
 	int identifier_type; /* 0=dummy, 1=connid, 2=resultid */
 	int identifier;
 	void *data;
@@ -103,6 +115,56 @@
 
 AST_LIST_HEAD(MYSQLidshead,ast_MYSQL_id) _mysql_ids_head;
 
+static void mysql_ds_destroy(void *data)
+{
+	/* Destroy any IDs owned by the channel */
+	struct ast_MYSQL_id *i;
+	if (AST_LIST_LOCK(&_mysql_ids_head)) {
+		ast_log(LOG_WARNING, "Unable to lock identifiers list\n");
+	} else {
+		AST_LIST_TRAVERSE_SAFE_BEGIN(&_mysql_ids_head, i, entries) {
+			if (i->owner == data) {
+				AST_LIST_REMOVE_CURRENT(entries);
+				if (i->identifier_type == AST_MYSQL_ID_CONNID) {
+					/* Drop connection */
+					mysql_close(i->data);
+				} else if (i->identifier_type == AST_MYSQL_ID_RESID) {
+					/* Drop result */
+					mysql_free_result(i->data);
+				}
+				ast_free(i);
+			}
+		}
+		AST_LIST_TRAVERSE_SAFE_END
+		AST_LIST_UNLOCK(&_mysql_ids_head);
+	}
+}
+
+static void mysql_ds_fixup(void *data, struct ast_channel *oldchan, struct ast_channel *newchan)
+{
+	/* Destroy any IDs owned by the channel */
+	struct ast_MYSQL_id *i;
+	if (AST_LIST_LOCK(&_mysql_ids_head)) {
+		ast_log(LOG_WARNING, "Unable to lock identifiers list\n");
+	} else {
+		AST_LIST_TRAVERSE_SAFE_BEGIN(&_mysql_ids_head, i, entries) {
+			if (i->owner == data) {
+				AST_LIST_REMOVE_CURRENT(entries);
+				if (i->identifier_type == AST_MYSQL_ID_CONNID) {
+					/* Drop connection */
+					mysql_close(i->data);
+				} else if (i->identifier_type == AST_MYSQL_ID_RESID) {
+					/* Drop result */
+					mysql_free_result(i->data);
+				}
+				ast_free(i);
+			}
+		}
+		AST_LIST_TRAVERSE_SAFE_END
+		AST_LIST_UNLOCK(&_mysql_ids_head);
+	}
+}
+
 /* helpful procs */
 static void *find_identifier(int identifier, int identifier_type)
 {
@@ -130,7 +192,7 @@
 	return res;
 }
 
-static int add_identifier(int identifier_type, void *data)
+static int add_identifier(struct ast_channel *chan, int identifier_type, void *data)
 {
 	struct ast_MYSQL_id *i = NULL, *j = NULL;
 	struct MYSQLidshead *headp = &_mysql_ids_head;
@@ -149,6 +211,7 @@
 		i->identifier = maxidentifier + 1;
 		i->identifier_type = identifier_type;
 		i->data = data;
+		i->owner = chan;
 		AST_LIST_INSERT_HEAD(headp, i, entries);
 		AST_LIST_UNLOCK(headp);
 	}
@@ -197,7 +260,7 @@
 
 static int add_identifier_and_set_asterisk_int(struct ast_channel *chan, char *varname, int identifier_type, void *data)
 {
-	return set_asterisk_int(chan, varname, add_identifier(identifier_type, data));
+	return set_asterisk_int(chan, varname, add_identifier(chan, identifier_type, data));
 }
 
 static int safe_scan_int(char **data, char *delim, int def)
@@ -454,12 +517,12 @@
 	return 0;
 }
 
-static int MYSQL_exec(struct ast_channel *chan, void *data)
+static int MYSQL_exec(struct ast_channel *chan, const char *data)
 {
 	int result;
 	char sresult[10];
 
-	ast_debug(5, "MYSQL: data=%s\n", (char *)data);
+	ast_debug(5, "MYSQL: data=%s\n", data);
 
 	if (!data) {
 		ast_log(LOG_WARNING, "MYSQL requires an argument (see manual)\n");
@@ -468,6 +531,17 @@
 
 	result = 0;
 
+	if (autoclear) {
+		struct ast_datastore *mysql_store = ast_channel_datastore_find(chan, &mysql_ds_info, NULL);
+		if (!mysql_store) {
+			if (!(mysql_store = ast_datastore_alloc(&mysql_ds_info, NULL))) {
+				ast_log(LOG_WARNING, "Unable to allocate new datastore.\n");
+			} else {
+				mysql_store->data = chan;
+				ast_channel_datastore_add(chan, mysql_store);
+			}
+		}
+	}
 	ast_mutex_lock(&_mysql_mutex);
 
 	if (strncasecmp("connect", data, strlen("connect")) == 0) {
@@ -485,7 +559,7 @@
 	} else if (strncasecmp("set", data, 3) == 0) {
 		result = aMYSQL_set(chan, ast_strdupa(data));
 	} else {
-		ast_log(LOG_WARNING, "Unknown argument to MYSQL application : %s\n", (char *)data);
+		ast_log(LOG_WARNING, "Unknown argument to MYSQL application : %s\n", data);
 		result = -1;
 	}
 
@@ -520,6 +594,9 @@
 				ast_log(LOG_WARNING, "Illegal value for 'nullvalue': '%s' (must be 'nullstring', 'null', or 'emptystring')\n", temp);
 			}
 		}
+		if ((temp = ast_variable_retrieve(cfg, "general", "autoclear")) && ast_true(temp)) {
+			autoclear = 1;
+		}
 		ast_config_destroy(cfg);
 	}
 

Modified: trunk/configs/mysql.conf.sample
URL: http://svn.asterisk.org/svn-view/asterisk-addons/trunk/configs/mysql.conf.sample?view=diff&rev=960&r1=959&r2=960
==============================================================================
--- trunk/configs/mysql.conf.sample (original)
+++ trunk/configs/mysql.conf.sample Mon Jun 29 17:33:29 2009
@@ -16,3 +16,9 @@
 ;
 nullvalue = nullstring
 
+; If set, autoclear will destroy allocated statement and connection resources
+; when the channel ends.  For most usage of the MYSQL app, this is what you
+; want, but it's conceivable that somebody is sharing MYSQL connections across
+; multiple channels, in which case, this should be set to 'no'.  Defaults to
+; 'no', as this was the original behavior.
+autoclear=yes




More information about the asterisk-addons-commits mailing list