[asterisk-commits] kmoore: branch kmoore/stasis-channel_events r383773 - /team/kmoore/stasis-cha...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Mar 25 15:30:48 CDT 2013


Author: kmoore
Date: Mon Mar 25 15:30:45 2013
New Revision: 383773

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=383773
Log:
Move channel blob handling callbacks into an ao2_container to avoid repeated string comparisons

Modified:
    team/kmoore/stasis-channel_events/main/manager_channels.c

Modified: team/kmoore/stasis-channel_events/main/manager_channels.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-channel_events/main/manager_channels.c?view=diff&rev=383773&r1=383772&r2=383773
==============================================================================
--- team/kmoore/stasis-channel_events/main/manager_channels.c (original)
+++ team/kmoore/stasis-channel_events/main/manager_channels.c Mon Mar 25 15:30:45 2013
@@ -37,6 +37,10 @@
 #include "asterisk/pbx.h"
 
 static struct stasis_message_router *channel_state_router;
+
+static struct ao2_container *channel_blob_handlers;
+
+#define BLOB_HANDLER_BUCKETS 57
 
 /*** DOCUMENTATION
 	<managerEvent language="en_US" name="Newchannel">
@@ -636,6 +640,47 @@
 		      ast_str_buffer(extra));
 }
 
+typedef void (*blob_handler_cb)(struct ast_channel_blob *obj);
+
+struct blob_handler {
+	char *type;
+	blob_handler_cb handler_cb;
+};
+
+static void blob_handler_destroy(void *obj)
+{
+	struct blob_handler *handler = obj;
+	ast_free(handler->type);
+}
+
+static void register_blob_handler(char *type, blob_handler_cb handler_cb)
+{
+	RAII_VAR(struct blob_handler *, handler, ao2_alloc(sizeof(*handler), blob_handler_destroy), ao2_cleanup);
+
+	if (!handler) {
+		return;
+	}
+
+	handler->type = ast_strdup(type);
+
+	if (!type) {
+		return;
+	}
+
+	handler->handler_cb = handler_cb;
+	ao2_link(channel_blob_handlers, handler);
+}
+
+static blob_handler_cb get_blob_handler(const char *type)
+{
+	RAII_VAR(struct blob_handler *, handler, ao2_find(channel_blob_handlers, type, OBJ_KEY), ao2_cleanup);
+	if (!handler) {
+		return NULL;
+	}
+
+	return handler->handler_cb;
+}
+
 /*!
  * \brief Callback processing messages on the channel topic.
  */
@@ -644,20 +689,32 @@
 			    struct stasis_message *message)
 {
 	struct ast_channel_blob *obj = stasis_message_data(message);
-
-	if (strcmp("varset", ast_channel_blob_type(obj)) == 0) {
-		channel_varset(obj);
-	} else if (strcmp("userevent", ast_channel_blob_type(obj)) == 0) {
-		channel_userevent(obj);
-	} else if (strcmp("hangup_request", ast_channel_blob_type(obj)) == 0) {
-		channel_hangup_request(obj);
-	}
+	blob_handler_cb handler = get_blob_handler(ast_channel_blob_type(obj));
+
+	if (handler) {
+		handler(obj);
+	}
+}
+
+static int blob_handler_hash(const void *obj, const int flags)
+{
+	const char *handler_type = (flags & OBJ_KEY) ? obj : ((struct blob_handler*) obj)->type;
+	return ast_str_case_hash(handler_type);
+}
+
+static int blob_handler_cmp(void *obj, void *arg, int flags)
+{
+	struct blob_handler *opt1 = obj, *opt2 = arg;
+	const char *handler_type = (flags & OBJ_KEY) ? arg : opt2->type;
+	return strcasecmp(opt1->type, handler_type) ? 0 : CMP_MATCH | CMP_STOP;
 }
 
 static void manager_channels_shutdown(void)
 {
 	stasis_message_router_unsubscribe(channel_state_router);
 	channel_state_router = NULL;
+	ao2_cleanup(channel_blob_handlers);
+	channel_blob_handlers = NULL;
 }
 
 int manager_channels_init(void)
@@ -696,5 +753,16 @@
 		return -1;
 	}
 
+	channel_blob_handlers = ao2_container_alloc(BLOB_HANDLER_BUCKETS, blob_handler_hash, blob_handler_cmp);
+
+	if (!channel_blob_handlers) {
+		manager_channels_shutdown();
+		return -1;
+	}
+
+	register_blob_handler("varset", channel_varset);
+	register_blob_handler("userevent", channel_userevent);
+	register_blob_handler("hangup_request", channel_hangup_request);
+
 	return 0;
 }




More information about the asterisk-commits mailing list