[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