[asterisk-commits] russell: branch russell/event_performance r183662 - in /team/russell/event_pe...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sun Mar 22 16:19:07 CDT 2009


Author: russell
Date: Sun Mar 22 16:19:02 2009
New Revision: 183662

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=183662
Log:
save off some progress on the next thing i'm doing ..

Modified:
    team/russell/event_performance/apps/app_voicemail.c
    team/russell/event_performance/channels/chan_dahdi.c
    team/russell/event_performance/include/asterisk/_private.h
    team/russell/event_performance/include/asterisk/event.h
    team/russell/event_performance/main/asterisk.c
    team/russell/event_performance/main/devicestate.c
    team/russell/event_performance/main/event.c
    team/russell/event_performance/res/ais/evt.c

Modified: team/russell/event_performance/apps/app_voicemail.c
URL: http://svn.digium.com/svn-view/asterisk/team/russell/event_performance/apps/app_voicemail.c?view=diff&rev=183662&r1=183661&r2=183662
==============================================================================
--- team/russell/event_performance/apps/app_voicemail.c (original)
+++ team/russell/event_performance/apps/app_voicemail.c Sun Mar 22 16:19:02 2009
@@ -6092,10 +6092,7 @@
 		return;
 	}
 
-	ast_event_queue_and_cache(event,
-		AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR,
-		AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR,
-		AST_EVENT_IE_END);
+	ast_event_queue_and_cache(event);
 }
 
 /*!

Modified: team/russell/event_performance/channels/chan_dahdi.c
URL: http://svn.digium.com/svn-view/asterisk/team/russell/event_performance/channels/chan_dahdi.c?view=diff&rev=183662&r1=183661&r2=183662
==============================================================================
--- team/russell/event_performance/channels/chan_dahdi.c (original)
+++ team/russell/event_performance/channels/chan_dahdi.c Sun Mar 22 16:19:02 2009
@@ -2305,10 +2305,7 @@
 		return;
 	}
 
-	ast_event_queue_and_cache(event,
-		AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR,
-		AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR,
-		AST_EVENT_IE_END);
+	ast_event_queue_and_cache(event);
 
 	if (!ast_strlen_zero(mailbox) && !ast_strlen_zero(mwimonitornotify)) {
 		snprintf(s, sizeof(s), "%s %s %d", mwimonitornotify, mailbox, thereornot);

Modified: team/russell/event_performance/include/asterisk/_private.h
URL: http://svn.digium.com/svn-view/asterisk/team/russell/event_performance/include/asterisk/_private.h?view=diff&rev=183662&r1=183661&r2=183662
==============================================================================
--- team/russell/event_performance/include/asterisk/_private.h (original)
+++ team/russell/event_performance/include/asterisk/_private.h Sun Mar 22 16:19:02 2009
@@ -28,7 +28,7 @@
 void dnsmgr_start_refresh(void);	/*!< Provided by dnsmgr.c */
 int dnsmgr_reload(void);		/*!< Provided by dnsmgr.c */
 void threadstorage_init(void);		/*!< Provided by threadstorage.c */
-void ast_event_init(void);		/*!< Provided by event.c */
+int ast_event_init(void);		/*!< Provided by event.c */
 int ast_device_state_engine_init(void);	/*!< Provided by devicestate.c */
 int astobj2_init(void);			/*!< Provided by astobj2.c */
 int ast_file_init(void);		/*!< Provided by file.c */

Modified: team/russell/event_performance/include/asterisk/event.h
URL: http://svn.digium.com/svn-view/asterisk/team/russell/event_performance/include/asterisk/event.h?view=diff&rev=183662&r1=183661&r2=183662
==============================================================================
--- team/russell/event_performance/include/asterisk/event.h (original)
+++ team/russell/event_performance/include/asterisk/event.h Sun Mar 22 16:19:02 2009
@@ -392,8 +392,10 @@
  * The purpose of caching events is so that the core can retain the last known
  * information for events that represent some sort of state.  That way, when
  * code needs to find out the current state, it can query the cache.
- */
-int ast_event_queue_and_cache(struct ast_event *event, ...);
+ *
+ * XXX FIX DOCS XXX
+ */
+int ast_event_queue_and_cache(struct ast_event *event);
 
 /*!
  * \brief Retrieve an event from the cache

Modified: team/russell/event_performance/main/asterisk.c
URL: http://svn.digium.com/svn-view/asterisk/team/russell/event_performance/main/asterisk.c?view=diff&rev=183662&r1=183661&r2=183662
==============================================================================
--- team/russell/event_performance/main/asterisk.c (original)
+++ team/russell/event_performance/main/asterisk.c Sun Mar 22 16:19:02 2009
@@ -3343,7 +3343,10 @@
 	}
 #endif
 
-	ast_event_init();
+	if (ast_event_init()) {
+		printf("%s", term_quit());
+		exit(1);
+	}
 
 	ast_makesocket();
 	sigemptyset(&sigs);

Modified: team/russell/event_performance/main/devicestate.c
URL: http://svn.digium.com/svn-view/asterisk/team/russell/event_performance/main/devicestate.c?view=diff&rev=183662&r1=183661&r2=183662
==============================================================================
--- team/russell/event_performance/main/devicestate.c (original)
+++ team/russell/event_performance/main/devicestate.c Sun Mar 22 16:19:02 2009
@@ -473,18 +473,7 @@
 		return;
 	}
 
-	/* Cache this event, replacing an event in the cache with the same
-	 * device name if it exists. */
-	if (event_type == AST_EVENT_DEVICE_STATE_CHANGE) {
-		ast_event_queue_and_cache(event,
-			AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR,
-			AST_EVENT_IE_EID, AST_EVENT_IE_PLTYPE_RAW, sizeof(struct ast_eid),
-			AST_EVENT_IE_END);
-	} else {
-		ast_event_queue_and_cache(event,
-			AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR,
-			AST_EVENT_IE_END);
-	}
+	ast_event_queue_and_cache(event);
 }
 
 /*! Called by the state change thread to find out what the state is, and then
@@ -673,13 +662,12 @@
 		AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, device,
 		AST_EVENT_IE_STATE, AST_EVENT_IE_PLTYPE_UINT, state,
 		AST_EVENT_IE_END);
-	
-	if (!event)
+
+	if (!event) {
 		return;
-
-	ast_event_queue_and_cache(event,
-		AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR,
-		AST_EVENT_IE_END);
+	}
+
+	ast_event_queue_and_cache(event);
 }
 
 static void handle_devstate_change(struct devstate_change *sc)

Modified: team/russell/event_performance/main/event.c
URL: http://svn.digium.com/svn-view/asterisk/team/russell/event_performance/main/event.c?view=diff&rev=183662&r1=183661&r2=183662
==============================================================================
--- team/russell/event_performance/main/event.c (original)
+++ team/russell/event_performance/main/event.c Sun Mar 22 16:19:02 2009
@@ -28,6 +28,7 @@
 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
 #include "asterisk/_private.h"
+
 #include "asterisk/event.h"
 #include "asterisk/linkedlists.h"
 #include "asterisk/dlinkedlists.h"
@@ -36,6 +37,7 @@
 #include "asterisk/unaligned.h"
 #include "asterisk/utils.h"
 #include "asterisk/taskprocessor.h"
+#include "asterisk/astobj2.h"
 
 struct ast_taskprocessor *event_dispatcher;
 
@@ -115,11 +117,41 @@
  * The event subscribers are indexed by which event they are subscribed to */
 static AST_RWDLLIST_HEAD(ast_event_sub_list, ast_event_sub) ast_event_subs[AST_EVENT_TOTAL];
 
-/*! \brief Cached events
- * The event cache is indexed on the event type.  The purpose of this is 
- * for events that express some sort of state.  So, when someone first
- * needs to know this state, it can get the last known state from the cache. */
-static AST_RWLIST_HEAD(ast_event_ref_list, ast_event_ref) ast_event_cache[AST_EVENT_TOTAL];
+static struct ao2_container *ast_event_cache[AST_EVENT_TOTAL];
+
+#ifdef LOW_MEMORY
+#define NUM_CACHE_BUCKETS 17
+#else
+#define NUM_CACHE_BUCKETS 563
+#endif
+
+static int ast_event_hash_mwi(const void *obj, const int flags);
+static int ast_event_cmp_mwi(void *obj, void *arg, int flags);
+static int ast_event_hash_devstate(const void *obj, const int flags);
+static int ast_event_cmp_devstate(void *obj, void *arg, int flags);
+static int ast_event_hash_devstate_change(const void *obj, const int flags);
+static int ast_event_cmp_devstate_change(void *obj, void *arg, int flags);
+
+/*!
+ * \brief Event types that are kept in the cache.
+ */
+static const struct {
+	ao2_hash_fn *hash_fn;
+	ao2_callback_fn *cmp_fn;
+} cached_event_types[AST_EVENT_TOTAL] = {
+	[AST_EVENT_MWI] = {
+		.hash_fn = ast_event_hash_mwi,
+		.cmp_fn  = ast_event_cmp_mwi,
+	},
+	[AST_EVENT_DEVICE_STATE] = {
+		.hash_fn = ast_event_hash_devstate,
+		.cmp_fn  = ast_event_cmp_devstate,
+	},
+	[AST_EVENT_DEVICE_STATE_CHANGE] = {
+		.hash_fn = ast_event_hash_devstate_change,
+		.cmp_fn  = ast_event_cmp_devstate_change,
+	},
+};
 
 /*!
  * The index of each entry _must_ match the event type number!
@@ -381,6 +413,7 @@
 /*! \brief Dump the event cache for the subscribed event type */
 void ast_event_dump_cache(const struct ast_event_sub *event_sub)
 {
+#if 0
 	struct ast_event_ref *event_ref;
 	enum ast_event_type type = event_sub->type;
 
@@ -398,6 +431,7 @@
 	}
 	AST_RWLIST_TRAVERSE_SAFE_END
 	AST_RWLIST_UNLOCK(&ast_event_cache[type]);
+#endif
 }
 
 static struct ast_event *gen_sub_event(struct ast_event_sub *sub)
@@ -896,10 +930,11 @@
 	ast_free(event);
 }
 
-static void ast_event_ref_destroy(struct ast_event_ref *event_ref)
-{
+static void ast_event_ref_destroy(void *obj)
+{
+	struct ast_event_ref *event_ref = obj;
+
 	ast_event_destroy(event_ref->event);
-	ast_free(event_ref);
 }
 
 static struct ast_event *ast_event_dup(const struct ast_event *event)
@@ -909,9 +944,10 @@
 
 	event_len = ast_event_get_size(event);
 
-	if (!(dup_event = ast_calloc(1, event_len)))
+	if (!(dup_event = ast_calloc(1, event_len))) {
 		return NULL;
-	
+	}
+
 	memcpy(dup_event, event, event_len);
 
 	return dup_event;
@@ -922,7 +958,7 @@
 	va_list ap;
 	enum ast_event_ie_type ie_type;
 	struct ast_event *dup_event = NULL;
-	struct ast_event_ref *event_ref;
+	//struct ast_event_ref *event_ref;
 	struct ast_event_ie_val *cache_arg;
 	AST_LIST_HEAD_NOLOCK_STATIC(cache_args, ast_event_ie_val);
 
@@ -960,7 +996,7 @@
 			"specifying at least one IE type!\n");
 		return NULL;
 	}
-
+#if 0
 	AST_RWLIST_RDLOCK(&ast_event_cache[type]);
 	AST_RWLIST_TRAVERSE_SAFE_BEGIN(&ast_event_cache[type], event_ref, entry) {
 		AST_LIST_TRAVERSE(&cache_args, cache_arg, entry) {
@@ -975,86 +1011,64 @@
 	}
 	AST_RWLIST_TRAVERSE_SAFE_END
 	AST_RWLIST_UNLOCK(&ast_event_cache[type]);
-
+#endif
 	return dup_event;
+}
+
+static struct ast_event_ref *alloc_event_ref(void)
+{
+	return ao2_alloc(sizeof(struct ast_event_ref), ast_event_ref_destroy);
 }
 
 /*! \brief Duplicate an event and add it to the cache
  * \note This assumes this index in to the cache is locked */
-static int ast_event_dup_and_cache(const struct ast_event *event)
+static int attribute_unused ast_event_dup_and_cache(const struct ast_event *event)
 {
 	struct ast_event *dup_event;
 	struct ast_event_ref *event_ref;
 
-	if (!(dup_event = ast_event_dup(event)))
-		return -1;
-	if (!(event_ref = ast_calloc(1, sizeof(*event_ref))))
-		return -1;
-	
+	if (!(dup_event = ast_event_dup(event))) {
+		return -1;
+	}
+
+	if (!(event_ref = alloc_event_ref())) {
+		return -1;
+	}
+
 	event_ref->event = dup_event;
 
-	AST_LIST_INSERT_TAIL(&ast_event_cache[ntohs(event->type)], event_ref, entry);
-
-	return 0;
-}
-
-int ast_event_queue_and_cache(struct ast_event *event, ...)
-{
-	va_list ap;
-	enum ast_event_type ie_type;
-	uint16_t host_event_type;
+	ao2_link(ast_event_cache[ast_event_get_type(event)], event_ref);
+
+	ao2_ref(event_ref, -1);
+
+	return 0;
+}
+
+int ast_event_queue_and_cache(struct ast_event *event)
+{
 	struct ast_event_ref *event_ref;
-	int res;
-	struct ast_event_ie_val *cache_arg;
-	AST_LIST_HEAD_NOLOCK_STATIC(cache_args, ast_event_ie_val);
-
-	host_event_type = ntohs(event->type);
-
-	/* Invalid type */
-	if (host_event_type >= AST_EVENT_TOTAL) {
-		ast_log(LOG_WARNING, "Someone tried to queue an event of invalid "
-			"type '%d'!\n", host_event_type);
-		return -1;
-	}
-
-	va_start(ap, event);
-	for (ie_type = va_arg(ap, enum ast_event_type);
-		ie_type != AST_EVENT_IE_END;
-		ie_type = va_arg(ap, enum ast_event_type))
-	{
-		cache_arg = alloca(sizeof(*cache_arg));
-		memset(cache_arg, 0, sizeof(*cache_arg));
-		cache_arg->ie_type = ie_type;
-		cache_arg->ie_pltype = va_arg(ap, enum ast_event_ie_pltype);
-		if (cache_arg->ie_pltype == AST_EVENT_IE_PLTYPE_RAW)
-			cache_arg->raw_datalen = va_arg(ap, size_t);
-		AST_LIST_INSERT_TAIL(&cache_args, cache_arg, entry);
-	}
-	va_end(ap);
-
-	if (AST_LIST_EMPTY(&cache_args)) {
-		ast_log(LOG_ERROR, "Events can not be cached without specifying at "
-			"least one IE type!\n");
-		return ast_event_queue(event);
-	}
- 
-	AST_RWLIST_WRLOCK(&ast_event_cache[host_event_type]);
-	AST_RWLIST_TRAVERSE_SAFE_BEGIN(&ast_event_cache[host_event_type], event_ref, entry) {
-		AST_LIST_TRAVERSE(&cache_args, cache_arg, entry) {
-			if (!match_ie_val(event_ref->event, cache_arg, event))
-				break;	
-		}
-		if (!cache_arg) {
-			/* All parameters were matched on this cache entry, so remove it */
-			AST_LIST_REMOVE_CURRENT(entry);
-			ast_event_ref_destroy(event_ref);
-		}
-	}
-	AST_RWLIST_TRAVERSE_SAFE_END;
-	res = ast_event_dup_and_cache(event);
-	AST_RWLIST_UNLOCK(&ast_event_cache[host_event_type]);
-
-	return (ast_event_queue(event) || res) ? -1 : 0;
+	ao2_callback_fn *cb_fn;
+	struct ao2_container *container;
+	struct ast_event_ref tmp_event_ref = {
+		.event = event,
+	};
+
+	if (!(container = ast_event_cache[ast_event_get_type(event)])) {
+		goto queue_event;
+	}
+
+	if (!(cb_fn = cached_event_types[ast_event_get_type(event)].cmp_fn)) {
+		goto queue_event;
+	}
+
+	/* Remove matches from the cache */
+	while ((event_ref = ao2_callback(container, OBJ_POINTER | OBJ_UNLINK,
+			cb_fn, &tmp_event_ref))) {
+		ao2_ref(event_ref, -1);
+	}
+
+queue_event:
+	return ast_event_queue(event);
 }
 
 static int handle_event(void *data)
@@ -1070,22 +1084,25 @@
 	AST_RWDLLIST_TRAVERSE(&ast_event_subs[host_event_type], sub, entry) {
 		struct ast_event_ie_val *ie_val;
 		AST_LIST_TRAVERSE(&sub->ie_vals, ie_val, entry) {
-			if (!match_ie_val(event_ref->event, ie_val, NULL))
+			if (!match_ie_val(event_ref->event, ie_val, NULL)) {
 				break;
-		}
-		if (ie_val)
+			}
+		}
+		if (ie_val) {
 			continue;
+		}
 		sub->cb(event_ref->event, sub->userdata);
 	}
 	AST_RWDLLIST_UNLOCK(&ast_event_subs[host_event_type]);
 
 	/* Now to subscribers to all event types */
 	AST_RWDLLIST_RDLOCK(&ast_event_subs[AST_EVENT_ALL]);
-	AST_RWDLLIST_TRAVERSE(&ast_event_subs[AST_EVENT_ALL], sub, entry)
+	AST_RWDLLIST_TRAVERSE(&ast_event_subs[AST_EVENT_ALL], sub, entry) {
 		sub->cb(event_ref->event, sub->userdata);
+	}
 	AST_RWDLLIST_UNLOCK(&ast_event_subs[AST_EVENT_ALL]);
 
-	ast_event_ref_destroy(event_ref);
+	ao2_ref(event_ref, -1);
 
 	return 0;
 }
@@ -1105,29 +1122,123 @@
 	}
 
 	/* If nobody has subscribed to this event type, throw it away now */
-	if (ast_event_check_subscriber(host_event_type, AST_EVENT_IE_END) 
-		== AST_EVENT_SUB_NONE) {
+	if (ast_event_check_subscriber(host_event_type, AST_EVENT_IE_END)
+			== AST_EVENT_SUB_NONE) {
 		ast_event_destroy(event);
 		return 0;
 	}
 
-	if (!(event_ref = ast_calloc(1, sizeof(*event_ref))))
-		return -1;
+	if (!(event_ref = ast_calloc(1, sizeof(*event_ref)))) {
+		return -1;
+	}
 
 	event_ref->event = event;
 
 	return ast_taskprocessor_push(event_dispatcher, handle_event, event_ref);
 }
 
-void ast_event_init(void)
+static int ast_event_hash_mwi(const void *obj, const int flags)
+{
+	const struct ast_event *event = obj;
+	const char *mailbox = ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX);
+	const char *context = ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT);
+	struct ast_str *str;
+
+	str = ast_str_alloca(strlen(mailbox) + strlen(context) + 1);
+
+	ast_str_set(&str, 0, "%s@%s", mailbox, context);
+
+	return ast_str_hash(ast_str_buffer(str));
+}
+
+static int ast_event_cmp_mwi(void *obj, void *arg, int flags)
+{
+	/* XXX */
+	return 0;
+}
+
+static int ast_event_hash_devstate(const void *obj, const int flags)
+{
+	/* XXX */
+	return 0;
+}
+
+static int ast_event_cmp_devstate(void *obj, void *arg, int flags)
+{
+	/* XXX */
+	return 0;
+}
+
+static int ast_event_hash_devstate_change(const void *obj, const int flags)
+{
+	/* XXX */
+	return 0;
+}
+
+static int ast_event_cmp_devstate_change(void *obj, void *arg, int flags)
+{
+	/* XXX */
+	return 0;
+}
+
+static int ast_event_hash(const void *obj, const int flags)
+{
+	const struct ast_event_ref *event_ref;
+	const struct ast_event *event;
+	ao2_hash_fn *hash_fn;
+
+	event_ref = obj;
+	event = event_ref->event;
+
+	if (!(hash_fn = cached_event_types[ast_event_get_type(event)].hash_fn)) {
+		return 0;
+	}
+
+	return hash_fn(event, flags);
+}
+
+static int ast_event_cmp(void *obj, void *arg, int flags)
+{
+	struct ast_event_ref *event_ref, *event_ref2;
+	struct ast_event *event, *event2;
+	ao2_callback_fn *cmp_fn;
+
+	event_ref = obj;
+	event = event_ref->event;
+
+	event_ref2 = arg;
+	event2 = event_ref2->event;
+
+	if (!(cmp_fn = cached_event_types[ast_event_get_type(event)].cmp_fn)) {
+		return 0;
+	}
+
+	return cmp_fn(event, event2, flags);
+}
+
+int ast_event_init(void)
 {
 	int i;
 
-	for (i = 0; i < AST_EVENT_TOTAL; i++)
+	for (i = 0; i < AST_EVENT_TOTAL; i++) {
 		AST_RWDLLIST_HEAD_INIT(&ast_event_subs[i]);
-
-	for (i = 0; i < AST_EVENT_TOTAL; i++)
-		AST_RWLIST_HEAD_INIT(&ast_event_cache[i]);
-
-	event_dispatcher = ast_taskprocessor_get("core_event_dispatcher", 0);
-}
+	}
+
+	for (i = 0; i < AST_EVENT_TOTAL; i++) {
+		if (!cached_event_types[i].hash_fn) {
+			/* This event type is not cached. */
+			continue;
+		}
+
+		if (!(ast_event_cache[i] = ao2_container_alloc(NUM_CACHE_BUCKETS,
+				ast_event_hash, ast_event_cmp))) {
+			return -1;
+		}
+	}
+
+	if (!(event_dispatcher = ast_taskprocessor_get("core_event_dispatcher", 0))) {
+		return -1;
+	}
+
+	return 0;
+}

Modified: team/russell/event_performance/res/ais/evt.c
URL: http://svn.digium.com/svn-view/asterisk/team/russell/event_performance/res/ais/evt.c?view=diff&rev=183662&r1=183661&r2=183662
==============================================================================
--- team/russell/event_performance/res/ais/evt.c (original)
+++ team/russell/event_performance/res/ais/evt.c Sun Mar 22 16:19:02 2009
@@ -112,34 +112,7 @@
 
 static void queue_event(struct ast_event *ast_event)
 {
-	enum ast_event_type type;
-
-	/*! 
-	 * \todo This hack macks me sad.  I need to come up with a better way to
-	 *       figure out whether an event should be cached or not, and what
-	 *       parameters to cache on.
-	 *
-	 *       As long as the types of events that are supported is limited,
-	 *       this isn't *terrible*, I guess.  Perhaps we should just define
-	 *       caching rules in the core, and make them configurable, and not
-	 *       have it be the job of the event publishers.
-	 */
-
-	type = ast_event_get_type(ast_event);
-
-	if (type == AST_EVENT_MWI) {
-		ast_event_queue_and_cache(ast_event,
-			AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR,
-			AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR,
-			AST_EVENT_IE_END);
-	} else if (type == AST_EVENT_DEVICE_STATE_CHANGE) {
-		ast_event_queue_and_cache(ast_event,
-			AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR,
-			AST_EVENT_IE_EID, AST_EVENT_IE_PLTYPE_RAW, sizeof(struct ast_eid),
-			AST_EVENT_IE_END);
-	} else {
-		ast_event_queue(ast_event);
-	}
+	ast_event_queue_and_cache(ast_event);
 }
 
 void evt_event_deliver_cb(SaEvtSubscriptionIdT sub_id,




More information about the asterisk-commits mailing list