[asterisk-commits] juggie: branch juggie/NoLossCDR r82582 - in /team/juggie/NoLossCDR: cdr/ incl...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Sep 17 10:20:05 CDT 2007
Author: juggie
Date: Mon Sep 17 10:20:05 2007
New Revision: 82582
URL: http://svn.digium.com/view/asterisk?view=rev&rev=82582
Log:
elixer: Moved cdr_adaptive_odbc multiple sink logic into the CDR core
Modified:
team/juggie/NoLossCDR/cdr/cdr_adaptive_odbc.c
team/juggie/NoLossCDR/cdr/cdr_csv.c
team/juggie/NoLossCDR/include/asterisk/cdr.h
team/juggie/NoLossCDR/main/cdr.c
Modified: team/juggie/NoLossCDR/cdr/cdr_adaptive_odbc.c
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/cdr/cdr_adaptive_odbc.c?view=diff&rev=82582&r1=82581&r2=82582
==============================================================================
--- team/juggie/NoLossCDR/cdr/cdr_adaptive_odbc.c (original)
+++ team/juggie/NoLossCDR/cdr/cdr_adaptive_odbc.c Mon Sep 17 10:20:05 2007
@@ -53,7 +53,7 @@
#include "asterisk/module.h"
#include "asterisk/logger.h"
-#define CONFIG "cdr_adaptive_odbc.conf"
+#define CONFIG "cdr_adaptive_odbc.conf"
static char *name = "Adaptive ODBC";
/* Optimization to reduce number of memory allocations */
@@ -71,21 +71,30 @@
AST_LIST_ENTRY(columns) list;
};
-struct tables {
+struct table {
char *connection;
char *table;
AST_LIST_HEAD_NOLOCK(odbc_columns, columns) columns;
- AST_RWLIST_ENTRY(tables) list;
};
-static AST_RWLIST_HEAD_STATIC(odbc_tables, tables);
+static int odbc_log(struct ast_cdr *, void *);
+
+static void free_table(void *data)
+{
+ struct columns *entry;
+ struct table *table = (struct table *) data;
+ while ((entry = AST_LIST_REMOVE_HEAD(&(table->columns), list))) {
+ ast_free(entry);
+ }
+ ast_free(table);
+}
static int load_config(void)
{
struct ast_config *cfg;
struct ast_variable *var;
const char *tmp, *catg;
- struct tables *tableptr;
+ struct table *tableptr;
struct columns *entry;
struct odbc_obj *obj;
char columnname[80];
@@ -214,25 +223,17 @@
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
ast_odbc_release_obj(obj);
- if (AST_LIST_FIRST(&(tableptr->columns)))
- AST_RWLIST_INSERT_TAIL(&odbc_tables, tableptr, list);
- else
+ if (AST_LIST_FIRST(&(tableptr->columns))) {
+ res = ast_cdr_register(name, catg, ast_module_info->description, odbc_log, free_table, tableptr);
+ if (res) {
+ ast_log(LOG_ERROR, "Unable to register Adaptive ODBC handler sink \"%s\"\n", catg);
+ if (tableptr)
+ free_table(tableptr);
+ }
+ } else
ast_free(tableptr);
}
return res;
-}
-
-static int free_config(void)
-{
- struct tables *table;
- struct columns *entry;
- while ((table = AST_RWLIST_REMOVE_HEAD(&odbc_tables, list))) {
- while ((entry = AST_LIST_REMOVE_HEAD(&(table->columns), list))) {
- ast_free(entry);
- }
- ast_free(table);
- }
- return 0;
}
static SQLHSTMT generic_prepare(struct odbc_obj *obj, void *data)
@@ -280,8 +281,7 @@
ast_log(LOG_ERROR, "Unable to allocate sufficient memory. Insert CDR '%s:%s' failed.\n", tableptr->connection, tableptr->table); \
ast_free(sql); \
ast_free(sql2); \
- AST_RWLIST_UNLOCK(&odbc_tables); \
- return -1; \
+ return AST_CDR_POST_FATAL; \
} \
} \
} while (0)
@@ -296,15 +296,14 @@
ast_log(LOG_ERROR, "Unable to allocate sufficient memory. Insert CDR '%s:%s' failed.\n", tableptr->connection, tableptr->table); \
ast_free(sql); \
ast_free(sql2); \
- AST_RWLIST_UNLOCK(&odbc_tables); \
- return -1; \
+ return AST_CDR_POST_FATAL; \
} \
} \
} while (0)
static int odbc_log(struct ast_cdr *cdr, void *data)
{
- struct tables *tableptr;
+ struct table *tableptr;
struct columns *entry;
struct odbc_obj *obj;
int lensql, lensql2, sizesql = maxsize, sizesql2 = maxsize2, newsize;
@@ -313,13 +312,10 @@
char colbuf[1024], *colptr;
SQLHSTMT stmt = NULL;
SQLLEN rows = 0;
-
- if (AST_RWLIST_RDLOCK(&odbc_tables)) {
- ast_log(LOG_ERROR, "Unable to lock table list. Insert CDR(s) failed.\n");
- return -1;
- }
-
- AST_LIST_TRAVERSE(&odbc_tables, tableptr, list) {
+ int res = AST_CDR_POST_OK;
+
+ tableptr = (struct table *) data;
+
lensql = snprintf(sql, sizesql, "INSERT INTO %s (", tableptr->table);
lensql2 = snprintf(sql2, sizesql2, " VALUES (");
@@ -558,13 +554,14 @@
}
if (rows == 0) {
ast_log(LOG_WARNING, "cdr_adaptive_odbc: Insert failed on '%s:%s'. CDR failed: %s\n", tableptr->connection, tableptr->table, sql);
+ /* We have to assume SQL error here I think, so don't retry. */
+ res = AST_CDR_POST_FATAL;
}
ast_odbc_release_obj(obj);
} else {
ast_log(LOG_WARNING, "cdr_adaptive_odbc: Unable to retrieve database handle for '%s:%s'. CDR failed: %s\n", tableptr->connection, tableptr->table, sql);
- }
- }
- AST_RWLIST_UNLOCK(&odbc_tables);
+ res = AST_CDR_POST_RETRY;
+ }
/* Next time, just allocate buffers that are that big to start with. */
if (sizesql > maxsize)
@@ -574,47 +571,30 @@
ast_free(sql);
ast_free(sql2);
+
+ return res;
+}
+
+static int unload_module(void)
+{
+ ast_cdr_unregister_all(name);
+
return 0;
}
-static int unload_module(void)
+static int load_module(void)
{
- ast_cdr_unregister(name, NULL);
- usleep(1);
- if (AST_RWLIST_WRLOCK(&odbc_tables)) {
- ast_cdr_register(name, NULL, ast_module_info->description, odbc_log, NULL);
- ast_log(LOG_ERROR, "Unable to lock column list. Unload failed.\n");
- return -1;
- }
-
- free_config();
- AST_RWLIST_UNLOCK(&odbc_tables);
+ load_config();
+
return 0;
}
-static int load_module(void)
-{
- if (AST_RWLIST_WRLOCK(&odbc_tables)) {
- ast_log(LOG_ERROR, "Unable to lock column list. Load failed.\n");
- return 0;
- }
-
- load_config();
- AST_RWLIST_UNLOCK(&odbc_tables);
- ast_cdr_register(name, NULL, ast_module_info->description, odbc_log, NULL);
- return 0;
-}
-
static int reload(void)
{
- if (AST_RWLIST_WRLOCK(&odbc_tables)) {
- ast_log(LOG_ERROR, "Unable to lock column list. Reload failed.\n");
- return -1;
- }
-
- free_config();
+ ast_cdr_unregister_all(name);
+
load_config();
- AST_RWLIST_UNLOCK(&odbc_tables);
+
return 0;
}
Modified: team/juggie/NoLossCDR/cdr/cdr_csv.c
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/cdr/cdr_csv.c?view=diff&rev=82582&r1=82581&r2=82582
==============================================================================
--- team/juggie/NoLossCDR/cdr/cdr_csv.c (original)
+++ team/juggie/NoLossCDR/cdr/cdr_csv.c Mon Sep 17 10:20:05 2007
@@ -314,7 +314,7 @@
{
if (mf)
fclose(mf);
- ast_cdr_unregister(name, NULL);
+ ast_cdr_unregister_all(name);
return 0;
}
@@ -325,7 +325,7 @@
if(!load_config(0))
return AST_MODULE_LOAD_DECLINE;
- res = ast_cdr_register(name, NULL, ast_module_info->description, csv_log, NULL);
+ res = ast_cdr_register(name, NULL, ast_module_info->description, csv_log, NULL, NULL);
if (res) {
ast_log(LOG_ERROR, "Unable to register CSV CDR handling\n");
if (mf)
Modified: team/juggie/NoLossCDR/include/asterisk/cdr.h
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/include/asterisk/cdr.h?view=diff&rev=82582&r1=82581&r2=82582
==============================================================================
--- team/juggie/NoLossCDR/include/asterisk/cdr.h (original)
+++ team/juggie/NoLossCDR/include/asterisk/cdr.h Mon Sep 17 10:20:05 2007
@@ -114,6 +114,7 @@
int ast_cdr_copy_vars(struct ast_cdr *to_cdr, struct ast_cdr *from_cdr);
typedef int (*ast_cdrbe)(struct ast_cdr *cdr, void *data);
+typedef void (*ast_cdrbe_cleanup)(void *data);
/*! \brief Return TRUE if CDR subsystem is enabled */
int check_cdr_enabled(void);
@@ -169,18 +170,27 @@
* \param name name associated with the particular CDR handler
* \param desc description of the CDR handler
* \param be function pointer to a CDR handler
+ * \param cleanup function pointer to a CDR sink cleanup handler
* Used to register a Call Detail Record handler.
* \retval 0 on success.
* \retval -1 on error
*/
-int ast_cdr_register(const char *name, const char *name_detail, const char *desc, ast_cdrbe be, void *be_data);
+int ast_cdr_register(const char *name, const char *name_detail, const char *desc, ast_cdrbe be, ast_cdrbe_cleanup cleanup, void *be_data);
/*!
* \brief Unregister a CDR handling engine
* \param name name of CDR handler to unregister
+ * \param name_detail name of CDR handler sink to unregister
* Unregisters a CDR by it's name
*/
void ast_cdr_unregister(const char *name, const char *name_detail);
+
+/*!
+ * \brief Unregister all sinks for a specific CDR handling engine
+ * \param name name of CDR handler to unregister
+ * Unregisters all CDR engine sinks by handler name
+ */
+void ast_cdr_unregister_all(const char *name);
/*!
* \brief Start a call
Modified: team/juggie/NoLossCDR/main/cdr.c
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/main/cdr.c?view=diff&rev=82582&r1=82581&r2=82582
==============================================================================
--- team/juggie/NoLossCDR/main/cdr.c (original)
+++ team/juggie/NoLossCDR/main/cdr.c Mon Sep 17 10:20:05 2007
@@ -67,6 +67,7 @@
char name_detail[20];
char desc[80];
ast_cdrbe be;
+ ast_cdrbe_cleanup cleanup;
void *be_data;
int cancel_thread;
int waiting_cdrs;
@@ -96,7 +97,7 @@
/*! Register a CDR driver. Each registered CDR driver generates a CDR
\return 0 on success, -1 on failure
*/
-int ast_cdr_register(const char *name, const char *name_detail, const char *desc, ast_cdrbe be, void *be_data)
+int ast_cdr_register(const char *name, const char *name_detail, const char *desc, ast_cdrbe be, ast_cdrbe_cleanup cleanup, void *be_data)
{
struct ast_cdr_beitem *i = NULL;
@@ -121,6 +122,7 @@
return -1;
i->be = be;
+ i->cleanup = cleanup;
i->cancel_thread = 0;
i->waiting_cdrs = 0;
ast_copy_string(i->name, name, sizeof(i->name));
@@ -159,9 +161,39 @@
ast_cond_destroy(&i->cdr_retry_cond);
AST_RWLIST_REMOVE_CURRENT(&be_list, list);
if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Unregistered '%s - %s' CDR backend\n", name, name_detail);
+ ast_verbose(VERBOSE_PREFIX_2 "Unregistered '%s - %s' CDR backend\n", i->name, i->name_detail);
+ if (i->cleanup)
+ i->cleanup(i->be_data);
+ ast_free(i);
+ break;
+ }
+ }
+ AST_RWLIST_TRAVERSE_SAFE_END;
+ AST_RWLIST_UNLOCK(&be_list);
+}
+
+/*! unregister all CDR drivers using the specifed name */
+void ast_cdr_unregister_all(const char *name)
+{
+ struct ast_cdr_beitem *i = NULL;
+
+ AST_RWLIST_WRLOCK(&be_list);
+ AST_RWLIST_TRAVERSE_SAFE_BEGIN(&be_list, i, list) {
+ if (!strcasecmp(name, i->name)) {
+ i->cancel_thread = 1;
+ /* signal the thread so it can exit */
+ ast_cond_signal(&i->cdr_pending_cond);
+ /* wait for thread to exit so we can clean up */
+ pthread_join(i->cdr_thread, NULL);
+ i->cdr_thread = AST_PTHREADT_NULL;
+ ast_cond_destroy(&i->cdr_pending_cond);
+ ast_cond_destroy(&i->cdr_retry_cond);
+ AST_RWLIST_REMOVE_CURRENT(&be_list, list);
+ if (option_verbose > 1)
+ ast_verbose(VERBOSE_PREFIX_2 "Unregistered '%s - %s' CDR backend\n", i->name, i->name_detail);
+ if (i->cleanup)
+ i->cleanup(i->be_data);
ast_free(i);
- break;
}
}
AST_RWLIST_TRAVERSE_SAFE_END;
@@ -870,7 +902,11 @@
ast_cli(fd, "CDR safe shut down: %s\n", safeshutdown ? "enabled" : "disabled");
AST_RWLIST_RDLOCK(&be_list);
AST_RWLIST_TRAVERSE(&be_list, beitem, list) {
- ast_cli(fd, "CDR registered backend: %s\n", beitem->name);
+ if (ast_strlen_zero(beitem->name_detail)) {
+ ast_cli(fd, "CDR registered backend: %s\n", beitem->name);
+ } else {
+ ast_cli(fd, "CDR registered backend: %s (%s)\n", beitem->name, beitem->name_detail);
+ }
}
AST_RWLIST_UNLOCK(&be_list);
}
More information about the asterisk-commits
mailing list