[asterisk-commits] russell: branch group/newcdr r202078 - /team/group/newcdr/main/cel.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Jun 19 17:16:46 CDT 2009


Author: russell
Date: Fri Jun 19 17:16:43 2009
New Revision: 202078

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=202078
Log:
Simplify app list parsing from do_reload(), rework appset handling

Modified:
    team/group/newcdr/main/cel.c

Modified: team/group/newcdr/main/cel.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/newcdr/main/cel.c?view=diff&rev=202078&r1=202077&r2=202078
==============================================================================
--- team/group/newcdr/main/cel.c (original)
+++ team/group/newcdr/main/cel.c Fri Jun 19 17:16:43 2009
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 2007, Digium, Inc.
+ * Copyright (C) 2007 - 2009, Digium, Inc.
  *
  * See http://www.asterisk.org for more information about
  * the Asterisk project. Please do not directly contact
@@ -20,6 +20,7 @@
  * \brief Channel Event Logging API
  *
  * \author Steve Murphy <murf at digium.com>
+ * \author Russell Bryant <russell at digium.com>
  */
 
 #include "asterisk.h"
@@ -36,12 +37,13 @@
 #include "asterisk/utils.h"
 #include "asterisk/config.h"
 #include "asterisk/cli.h"
+#include "asterisk/astobj2.h"
 
 /*! Is the CEL subsystem enabled ? */
-static unsigned int cel_enabled;
+static unsigned char cel_enabled;
 
 /*! \brief CEL is off by default */
-static const unsigned int CEL_ENALBED_DEFAULT = 0;
+static const unsigned char CEL_ENALBED_DEFAULT = 0;
 
 /*! 
  * \brief which events we want to track 
@@ -53,13 +55,24 @@
 /*! \brief Track no events by default. */
 static const int64_t CEL_DEFAULT_EVENTS = 0;
 
-static struct ast_hashtab *appset;
+static const int NUM_APP_BUCKETS = 97;
+
+static struct ao2_container *appset;
 
 static char cel_dateformat[256];
 
 unsigned int ast_cel_check_enabled(void)
 {
 	return cel_enabled;
+}
+
+static int print_app(void *obj, void *arg, int flags)
+{
+	struct ast_cli_args *a = arg;
+
+	ast_cli(a->fd, "CEL Tracking Application: %s\n", (const char *) obj);
+
+	return 0;
 }
 
 static char *handle_cli_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
@@ -100,6 +113,8 @@
 			ast_cli(a->fd, "CEL Tracking Event: %s\n", name);
 		}
 	}
+
+	ao2_callback(appset, OBJ_NODATA, print_app, a);
 
 	ast_event_lock_subscribers(AST_EVENT_CEL);
 	while ((sub = ast_event_next_subscriber(AST_EVENT_CEL, sub))) {
@@ -203,6 +218,35 @@
 	}
 }
 
+static void parse_apps(const char *val)
+{
+	char *apps = ast_strdupa(val);
+	char *cur_app;
+
+	if (!ast_cel_track_event(AST_CEL_APP_START) && !ast_cel_track_event(AST_CEL_APP_END)) {
+		ast_log(LOG_WARNING, "An apps= config line, but not tracking APP events\n");
+		return;
+	}
+
+	while ((cur_app = strsep(&apps, ","))) {
+		char *app;
+
+		cur_app = ast_strip(cur_app);
+		if (ast_strlen_zero(cur_app)) {
+			continue;
+		}
+
+		if (!(app = ao2_alloc(strlen(cur_app) + 1, NULL))) {
+			continue;
+		}
+		strcpy(app, cur_app);
+
+		ao2_link(appset, app);
+		ao2_ref(app, -1);
+		app = NULL;
+	}
+}
+
 AST_MUTEX_DEFINE_STATIC(reload_lock);
 
 static int do_reload(void)
@@ -219,19 +263,7 @@
 	cel_enabled = CEL_ENALBED_DEFAULT;
 	eventset = CEL_DEFAULT_EVENTS;
 
-	if (appset) {
-		char *str;
-		/* a pre-existing hash table == destroy it */
-		/* first, free all the entries */
-		struct ast_hashtab_iter *it;
-		it = ast_hashtab_start_traversal(appset);
-		while ((str = ast_hashtab_next(it))) {
-			free(str);
-		}
-		ast_hashtab_end_traversal(it);
-		ast_hashtab_destroy(appset, NULL);
-		appset = 0;
-	}
+	ao2_callback(appset, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL);
 
 	config = ast_config_load2("cel.conf", "cel", config_flags);
 
@@ -258,73 +290,7 @@
 	}
 
 	if ((val = ast_variable_retrieve(config, "general", "apps"))) {
-		char *t1, *t2, *t3, *myapplist = ast_strdup(val);
-		if (!ast_cel_track_event(AST_CEL_APP_START) && !ast_cel_track_event(AST_CEL_APP_END)) {
-			ast_log(LOG_ERROR, "An apps= config line, but not tracking APP events!\n");
-		} else {
-			int commacount = 0;
-			t1 = myapplist;
-			t2 = t1;
-			while (t2) {
-				t2 = strchr(t2,',');
-				if (t2) {
-					t2++;
-					commacount++;
-				}
-			}
-			/* form a hash table */
-			appset = ast_hashtab_create(commacount+1, ast_hashtab_compare_strings_nocase,
-										ast_hashtab_resize_none,
-										ast_hashtab_newsize_none,
-										ast_hashtab_hash_string_nocase,1);
-			while (t1 && *t1) {
-				t2 = strchr(t1,',');
-				if (!t2) {
-					t2 = t1 + strlen(t1) - 1;
-				} else {
-					*t2 = 0;
-				}
-
-				/*push t1 to the first non-blank char */
-				while (t1 && *t1 && isspace(*t1)) {
-					t1++;
-				}
-				if (t2 == t1) {
-					ast_log(LOG_ERROR, "A comma with no preceeding event name? --Ignored\n");
-					t1 = t2+1;
-					continue;
-				}
-				if (!(*t1)) {
-					ast_log(LOG_ERROR, "no events to log? Turning off CEL capability!\n");
-					cel_enabled = 0;
-					break;
-				}
-				/* pull t3 (a copy of t2) to last non-blank char */
-				t3 = t2;
-				if (!(*t2)) {
-					t3 = t2-1;
-				}
-				while (t3 && *t3 && isspace(*t3)) {
-					t3--;
-				}
-				*(t3+1) = 0;
-				/* t1 now points to null-terminated entry */
-				/* while just a few apps would be OK to put in a linked list,
-				   If there are dozens, a linked list search would be really
-				   horribly slow and therefore bad.
-				   So, let's put these in a hash table
-				*/
-				t3 = strdup(t1);
-				if (!ast_hashtab_insert_safe(appset, t3)) {
-					ast_log(LOG_ERROR, "The %s app in the apps= line is repeated!\n", t3);
-					free(t3);
-				}
-				t1 = t2+1;
-			}
-		}
-		if (myapplist) {
-			free(myapplist);
-		}
+		parse_apps(val);
 	}
 
 return_cleanup:
@@ -544,9 +510,11 @@
 	ast_debug(3, "CEL event tracked: %s\n", ast_cel_get_type_name(event_type));
 
 	if (event_type == AST_CEL_APP_START || event_type == AST_CEL_APP_END) {
-		if (!ast_hashtab_lookup(appset, chan->appl)) {
+		char *app;
+		if (!(app = ao2_find(appset, (char *) chan->appl, OBJ_POINTER))) {
 			return;
 		}
+		ao2_ref(app, -1);
 	}
 
 	if (peer) {
@@ -594,23 +562,45 @@
 	}
 }
 
+static int app_hash(const void *obj, const int flags)
+{
+	return ast_str_case_hash((const char *) obj);
+}
+
+static int app_cmp(void *obj, void *arg, int flags)
+{
+	const char *app1 = obj, *app2 = arg;
+
+	return !strcasecmp(app1, app2) ? CMP_MATCH | CMP_STOP : 0;
+}
 
 int ast_cel_engine_init(void)
 {
-	int res;
-
-	res = ast_cli_register(&cli_status);
-
-	if (!res) {
-		res = do_reload();
-	}
-
-	return res;
+	if (!(appset = ao2_container_alloc(NUM_APP_BUCKETS, app_hash, app_cmp))) {
+		return -1;
+	}
+
+	if (do_reload()) {
+		ao2_ref(appset, -1);
+		appset = NULL;
+		return -1;
+	}
+
+	if (ast_cli_register(&cli_status)) {
+		ao2_ref(appset, -1);
+		appset = NULL;
+		return -1;
+	}
+
+	return 0;
 }
 
 void ast_cel_engine_term(void)
 {
-	/* not much to do now, but there may be in the near-term future */
+	if (appset) {
+		ao2_ref(appset, -1);
+		appset = NULL;
+	}
 }
 
 int ast_cel_engine_reload(void)




More information about the asterisk-commits mailing list