[asterisk-commits] russell: trunk r370664 - /trunk/main/event.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jul 31 15:34:02 CDT 2012


Author: russell
Date: Tue Jul 31 15:33:57 2012
New Revision: 370664

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=370664
Log:
Move event cache updates into event processing thread.

Prior to this patch, updating the device state cache was done by the thread
that originated the event.  It would update the cache and then queue the event
up for another thread to dispatch.  This thread moves the cache updating part
to be in the same thread as event dispatching.

I was working with someone on a heavily loaded Asterisk system and while
reviewing backtraces of the system while it was having problems, I noticed that
there were a lot of threads contending for the lock on the event cache.  By
simply moving this into a single thread, this helped performance *a lot* and
alleviated some deadlock-like symptoms.

Review: https://reviewboard.asterisk.org/r/2066/


Modified:
    trunk/main/event.c

Modified: trunk/main/event.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/event.c?view=diff&rev=370664&r1=370663&r2=370664
==============================================================================
--- trunk/main/event.c (original)
+++ trunk/main/event.c Tue Jul 31 15:33:57 2012
@@ -103,6 +103,7 @@
  */
 struct ast_event_ref {
 	struct ast_event *event;
+	unsigned int cache;
 };
 
 struct ast_event_ie_val {
@@ -1470,23 +1471,6 @@
 	ao2_unlock(cache);
 }
 
-int ast_event_queue_and_cache(struct ast_event *event)
-{
-	struct ao2_container *container;
-
-	container = ast_event_cache[ast_event_get_type(event)].container;
-	if (!container) {
-		ast_log(LOG_WARNING, "cache requested for non-cached event type\n");
-	} else {
-		event_update_cache(container, event);
-	}
-
-	if (ast_event_queue(event)) {
-		ast_event_destroy(event);
-	}
-	return 0;
-}
-
 static int handle_event(void *data)
 {
 	struct ast_event_ref *event_ref = data;
@@ -1496,6 +1480,16 @@
 		AST_EVENT_ALL
 	};
 	int i;
+
+	if (event_ref->cache) {
+		struct ao2_container *container;
+		container = ast_event_cache[ast_event_get_type(event_ref->event)].container;
+		if (!container) {
+			ast_log(LOG_WARNING, "cache requested for non-cached event type\n");
+		} else {
+			event_update_cache(container, event_ref->event);
+		}
+	}
 
 	for (i = 0; i < ARRAY_LEN(event_types); i++) {
 		AST_RWDLLIST_RDLOCK(&ast_event_subs[event_types[i]]);
@@ -1522,7 +1516,7 @@
 	return 0;
 }
 
-int ast_event_queue(struct ast_event *event)
+static int _ast_event_queue(struct ast_event *event, unsigned int cache)
 {
 	struct ast_event_ref *event_ref;
 	uint16_t host_event_type;
@@ -1549,6 +1543,7 @@
 	}
 
 	event_ref->event = event;
+	event_ref->cache = cache;
 
 	res = ast_taskprocessor_push(event_dispatcher, handle_event, event_ref);
 	if (res) {
@@ -1556,6 +1551,16 @@
 		ao2_ref(event_ref, -1);
 	}
 	return res;
+}
+
+int ast_event_queue(struct ast_event *event)
+{
+	return _ast_event_queue(event, 0);
+}
+
+int ast_event_queue_and_cache(struct ast_event *event)
+{
+	return _ast_event_queue(event, 1);
 }
 
 static int ast_event_hash_mwi(const void *obj, const int flags)




More information about the asterisk-commits mailing list