[asterisk-commits] tilghman: branch tilghman/odbc_tx_support r131302 - in /team/tilghman/odbc_tx...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Jul 16 14:01:18 CDT 2008
Author: tilghman
Date: Wed Jul 16 14:01:17 2008
New Revision: 131302
URL: http://svn.digium.com/view/asterisk?view=rev&rev=131302
Log:
Start working with transactions within func_odbc
Modified:
team/tilghman/odbc_tx_support/ (props changed)
team/tilghman/odbc_tx_support/funcs/func_odbc.c
team/tilghman/odbc_tx_support/include/asterisk/res_odbc.h
team/tilghman/odbc_tx_support/res/res_odbc.c
Propchange: team/tilghman/odbc_tx_support/
------------------------------------------------------------------------------
automerge = *
Modified: team/tilghman/odbc_tx_support/funcs/func_odbc.c
URL: http://svn.digium.com/view/asterisk/team/tilghman/odbc_tx_support/funcs/func_odbc.c?view=diff&rev=131302&r1=131301&r2=131302
==============================================================================
--- team/tilghman/odbc_tx_support/funcs/func_odbc.c (original)
+++ team/tilghman/odbc_tx_support/funcs/func_odbc.c Wed Jul 16 14:01:17 2008
@@ -131,6 +131,7 @@
struct acf_odbc_query *query;
char *t, buf[2048], varname[15];
int i, dsn, bogus_chan = 0;
+ int transactional = 0;
AST_DECLARE_APP_ARGS(values,
AST_APP_ARG(field)[100];
);
@@ -204,17 +205,36 @@
}
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++) {
+ 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, buf))) {
+ break;
+ }
+ }
+
+ if (obj && !transactional) {
+ ast_odbc_release_obj(obj);
+ }
+ }
+
AST_LIST_UNLOCK(&queries);
-
- for (dsn = 0; dsn < 5; dsn++) {
- if (!ast_strlen_zero(query->writehandle[dsn])) {
- obj = ast_odbc_request_obj(query->writehandle[dsn], 0);
- if (obj)
- stmt = ast_odbc_direct_execute(obj, generic_execute, buf);
- }
- if (stmt)
- break;
- }
if (stmt) {
/* Rows affected */
@@ -232,7 +252,7 @@
SQLCloseCursor(stmt);
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
}
- if (obj)
+ if (obj && !transactional)
ast_odbc_release_obj(obj);
if (chan)
Modified: team/tilghman/odbc_tx_support/include/asterisk/res_odbc.h
URL: http://svn.digium.com/view/asterisk/team/tilghman/odbc_tx_support/include/asterisk/res_odbc.h?view=diff&rev=131302&r1=131301&r2=131302
==============================================================================
--- team/tilghman/odbc_tx_support/include/asterisk/res_odbc.h (original)
+++ team/tilghman/odbc_tx_support/include/asterisk/res_odbc.h Wed Jul 16 14:01:17 2008
@@ -119,7 +119,14 @@
struct odbc_obj *ast_odbc_request_obj2(const char *name, struct ast_flags flags);
#endif
+#ifdef DEBUG_THREADS
+struct odbc_obj *_ast_odbc_request_obj(const char *name, int check, const char *file, const char *function, int lineno);
+#define ast_odbc_request_obj(a, b) _ast_odbc_request_obj(a, b, __FILE__, __PRETTY_FUNCTION__, __LINE__)
+#else
struct odbc_obj *ast_odbc_request_obj(const char *name, int check);
+#endif
+
+struct odbc_obj *ast_odbc_retrieve_transaction_obj(struct ast_channel *chan, const char *objname);
/*!
* \brief Releases an ODBC object previously allocated by odbc_request_obj()
Modified: team/tilghman/odbc_tx_support/res/res_odbc.c
URL: http://svn.digium.com/view/asterisk/team/tilghman/odbc_tx_support/res/res_odbc.c?view=diff&rev=131302&r1=131301&r2=131302
==============================================================================
--- team/tilghman/odbc_tx_support/res/res_odbc.c (original)
+++ team/tilghman/odbc_tx_support/res/res_odbc.c Wed Jul 16 14:01:17 2008
@@ -65,7 +65,7 @@
unsigned int forcecommit:1; /*!< Should uncommitted transactions be auto-committed on handle release? */
unsigned int isolation:2; /*!< Flags for how the DB should deal with data in other, uncommitted transactions */
unsigned int limit; /*!< 1023 wasn't enough for some people */
- unsigned int count; /*!< Running count of pooled connections */
+ int count; /*!< Running count of pooled connections */
unsigned int idlecheck; /*!< Recheck the connection if it is idle for this long */
struct ao2_container *obj_container;
};
@@ -149,7 +149,7 @@
if (!chan && obj && obj->txf && obj->txf->owner) {
chan = obj->txf->owner;
- } else {
+ } else if (!chan) {
/* No channel == no transaction */
return NULL;
}
@@ -955,7 +955,6 @@
}
if (!obj && (class->count < class->limit)) {
- class->count++;
obj = ao2_alloc(sizeof(*obj), odbc_obj_destructor);
if (!obj) {
ao2_ref(class, -1);
@@ -968,10 +967,10 @@
ast_log(LOG_WARNING, "Failed to connect to %s\n", name);
ao2_ref(obj, -1);
obj = NULL;
- class->count--;
} else {
obj->used = 1;
ao2_link(class->obj_container, obj);
+ ast_atomic_fetchadd_int(&class->count, +1);
}
}
} else if (ast_test_flag(&flags, RES_ODBC_INDEPENDENT_CONNECTION)) {
@@ -987,7 +986,6 @@
}
if (!obj) {
- class->count++;
obj = ao2_alloc(sizeof(*obj), odbc_obj_destructor);
if (!obj) {
ao2_ref(class, -1);
@@ -1000,10 +998,10 @@
ast_log(LOG_WARNING, "Failed to connect to %s\n", name);
ao2_ref(obj, -1);
obj = NULL;
- class->count--;
} else {
obj->used = 1;
ao2_link(class->obj_container, obj);
+ ast_atomic_fetchadd_int(&class->count, +1);
}
}
} else {
@@ -1055,10 +1053,46 @@
return obj;
}
+#ifdef DEBUG_THREADS
+struct odbc_obj *_ast_odbc_request_obj(const char *name, int check, const char *file, const char *function, int lineno)
+#else
struct odbc_obj *ast_odbc_request_obj(const char *name, int check)
+#endif
{
struct ast_flags flags = { check ? RES_ODBC_SANITY_CHECK : 0 };
+#ifdef DEBUG_THREADS
+ return _ast_odbc_request_obj2(name, flags, file, function, lineno);
+#else
return ast_odbc_request_obj2(name, flags);
+#endif
+}
+
+struct odbc_obj *ast_odbc_retrieve_transaction_obj(struct ast_channel *chan, const char *objname)
+{
+ struct ast_datastore *txn_store;
+ AST_LIST_HEAD(, odbc_txn_frame) *oldlist;
+ struct odbc_txn_frame *txn = NULL;
+
+ if (!chan) {
+ /* No channel == no transaction */
+ return NULL;
+ }
+
+ if ((txn_store = ast_channel_datastore_find(chan, &txn_info, NULL))) {
+ oldlist = txn_store->data;
+ } else {
+ return NULL;
+ }
+
+ AST_LIST_LOCK(oldlist);
+ AST_LIST_TRAVERSE(oldlist, txn, list) {
+ if (txn->obj && txn->obj->parent && !strcmp(txn->obj->parent->name, objname)) {
+ AST_LIST_UNLOCK(oldlist);
+ return txn->obj;
+ }
+ }
+ AST_LIST_UNLOCK(oldlist);
+ return NULL;
}
static odbc_status odbc_obj_disconnect(struct odbc_obj *obj)
More information about the asterisk-commits
mailing list