Merged revisions 310415 via svnmerge from
authorTilghman Lesher <tilghman@meg.abyt.es>
Sat, 12 Mar 2011 20:08:19 +0000 (20:08 +0000)
committerTilghman Lesher <tilghman@meg.abyt.es>
Sat, 12 Mar 2011 20:08:19 +0000 (20:08 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.8

................
  r310415 | tilghman | 2011-03-12 14:05:46 -0600 (Sat, 12 Mar 2011) | 14 lines

  Merged revisions 310414 via svnmerge from
  https://origsvn.digium.com/svn/asterisk/branches/1.6.2

  ........
    r310414 | tilghman | 2011-03-12 13:51:23 -0600 (Sat, 12 Mar 2011) | 7 lines

    Transactional handles should be used for the insertbuf, if available.

    Also, fix a possible resource leak.

    (closes issue #18943)
     Reported by: irroot
  ........
................

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@310416 65c4cc65-6c06-0410-ace0-fbb531ad65f3

funcs/func_odbc.c

index 10cf50e..fad548a 100644 (file)
@@ -304,29 +304,30 @@ static int acf_odbc_write(struct ast_channel *chan, const char *cmd, char *s, co
                        pbx_builtin_setvar_helper(chan, varname, NULL);
                }
                pbx_builtin_setvar_helper(chan, "VALUE", NULL);
+       }
 
-               /*!\note
-                * Okay, this part is confusing.  Transactions belong to a single database
-                * handle.  Therefore, when working with transactions, we CANNOT failover
-                * to multiple DSNs.  We MUST have a single handle all the way through the
-                * transaction, or else we CANNOT enforce atomicity.
-                */
-               for (dsn = 0; dsn < 5; dsn++) {
+       /*!\note
+        * Okay, this part is confusing.  Transactions belong to a single database
+        * handle.  Therefore, when working with transactions, we CANNOT failover
+        * to multiple DSNs.  We MUST have a single handle all the way through the
+        * transaction, or else we CANNOT enforce atomicity.
+        */
+       for (dsn = 0; dsn < 5; dsn++) {
+               if (!ast_strlen_zero(query->writehandle[dsn])) {
                        if (transactional) {
                                /* This can only happen second time through or greater. */
                                ast_log(LOG_WARNING, "Transactions do not work well with multiple DSNs for 'writehandle'\n");
                        }
 
-                       if (!ast_strlen_zero(query->writehandle[dsn])) {
-                               if ((obj = ast_odbc_retrieve_transaction_obj(chan, query->writehandle[dsn]))) {
-                                       transactional = 1;
-                               } else {
-                                       obj = ast_odbc_request_obj(query->writehandle[dsn], 0);
-                                       transactional = 0;
-                               }
-                               if (obj && (stmt = ast_odbc_direct_execute(obj, generic_execute, ast_str_buffer(buf)))) {
-                                       break;
-                               }
+                       if ((obj = ast_odbc_retrieve_transaction_obj(chan, query->writehandle[dsn]))) {
+                               transactional = 1;
+                       } else {
+                               obj = ast_odbc_request_obj(query->writehandle[dsn], 0);
+                               transactional = 0;
+                       }
+
+                       if (obj && (stmt = ast_odbc_direct_execute(obj, generic_execute, ast_str_buffer(buf)))) {
+                               break;
                        }
 
                        if (obj && !transactional) {
@@ -343,9 +344,27 @@ static int acf_odbc_write(struct ast_channel *chan, const char *cmd, char *s, co
        if (stmt && rows == 0 && ast_str_strlen(insertbuf) != 0) {
                SQLCloseCursor(stmt);
                SQLFreeHandle(SQL_HANDLE_STMT, stmt);
-               for (dsn = 0; dsn < 5; dsn++) {
+               if (obj && !transactional) {
+                       ast_odbc_release_obj(obj);
+                       obj = NULL;
+               }
+
+               for (transactional = 0, dsn = 0; dsn < 5; dsn++) {
                        if (!ast_strlen_zero(query->writehandle[dsn])) {
-                               obj = ast_odbc_request_obj(query->writehandle[dsn], 0);
+                               if (transactional) {
+                                       /* This can only happen second time through or greater. */
+                                       ast_log(LOG_WARNING, "Transactions do not work well with multiple DSNs for 'writehandle'\n");
+                               } else if (obj) {
+                                       ast_odbc_release_obj(obj);
+                                       obj = NULL;
+                               }
+
+                               if ((obj = ast_odbc_retrieve_transaction_obj(chan, query->writehandle[dsn]))) {
+                                       transactional = 1;
+                               } else {
+                                       obj = ast_odbc_request_obj(query->writehandle[dsn], 0);
+                                       transactional = 0;
+                               }
                                if (obj) {
                                        stmt = ast_odbc_direct_execute(obj, generic_execute, ast_str_buffer(insertbuf));
                                }
@@ -355,8 +374,6 @@ static int acf_odbc_write(struct ast_channel *chan, const char *cmd, char *s, co
                                SQLRowCount(stmt, &rows);
                                break;
                        }
-                       ast_odbc_release_obj(obj);
-                       obj = NULL;
                }
        } else if (stmt) {
                status = "SUCCESS";