[asterisk-commits] kmoore: trunk r390830 - in /trunk: include/asterisk/ main/ tests/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Jun 7 07:57:05 CDT 2013


Author: kmoore
Date: Fri Jun  7 07:56:56 2013
New Revision: 390830

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=390830
Log:
Rework stasis cache clear events

Stasis cache clear message payloads now consist of a stasis_message
representative of the message to be cleared from the cache. This allows
multiple parallel caches to coexist and be cleared properly by the same
cache clear message even when keyed on different fields.

This change fixes a bug where multiple cache clears could be posted for
channels. The cache clear is now produced in the destructor instead of
ast_hangup.

Additionally, dummy channels are no longer capable of producing channel
snapshots.

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

Modified:
    trunk/include/asterisk/stasis.h
    trunk/main/bridging.c
    trunk/main/channel.c
    trunk/main/endpoints.c
    trunk/main/stasis_cache.c
    trunk/main/stasis_channels.c
    trunk/tests/test_stasis.c

Modified: trunk/include/asterisk/stasis.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/stasis.h?view=diff&rev=390830&r1=390829&r2=390830
==============================================================================
--- trunk/include/asterisk/stasis.h (original)
+++ trunk/include/asterisk/stasis.h Fri Jun  7 07:56:56 2013
@@ -502,40 +502,32 @@
 };
 
 /*!
- * \brief Cache clear message.
- */
-struct stasis_cache_clear {
-	/*! Type of object being cleared from the cache */
-	struct stasis_message_type *type;
-	/*! Id of the object being cleared from the cache */
-	char id[];
-};
-
-/*!
- * \brief Message type for \ref stasis_cache_clear.
+ * \brief Message type for clearing a message from a stasis cache.
  * \since 12
  */
 struct stasis_message_type *stasis_cache_clear_type(void);
 
+/*! @} */
+
+/*! @{ */
+
+/*!
+ * \brief A topic wrapper, which caches certain messages.
+ * \since 12
+ */
+struct stasis_caching_topic;
+
 /*!
  * \brief A message which instructs the caching topic to remove an entry from its cache.
- * \param type Message type.
- * \param id Unique id of the snapshot to clear.
+ *
+ * \param message Message representative of the cache entry that should be cleared.
+ *     This will become the data held in the stasis_cache_clear message.
+ *
  * \return Message which, when sent to the \a topic, will clear the item from the cache.
  * \return \c NULL on error.
  * \since 12
  */
-struct stasis_message *stasis_cache_clear_create(struct stasis_message_type *type, const char *id);
-
-/*! @} */
-
-/*! @{ */
-
-/*!
- * \brief A topic wrapper, which caches certain messages.
- * \since 12
- */
-struct stasis_caching_topic;
+struct stasis_message *stasis_cache_clear_create(struct stasis_message *message);
 
 /*!
  * \brief Callback extract a unique identity from a snapshot message.

Modified: trunk/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/bridging.c?view=diff&rev=390830&r1=390829&r2=390830
==============================================================================
--- trunk/main/bridging.c (original)
+++ trunk/main/bridging.c Fri Jun  7 07:56:56 2013
@@ -1283,17 +1283,32 @@
 	}
 }
 
+static struct stasis_message *create_bridge_snapshot_message(struct ast_bridge *bridge)
+{
+	RAII_VAR(struct ast_bridge_snapshot *, snapshot, NULL, ao2_cleanup);
+	snapshot = ast_bridge_snapshot_create(bridge);
+	if (!snapshot) {
+		return NULL;
+	}
+
+	return stasis_message_create(ast_bridge_snapshot_type(), snapshot);
+}
+
 static void destroy_bridge(void *obj)
 {
 	struct ast_bridge *bridge = obj;
-	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
+	RAII_VAR(struct stasis_message *, clear_msg, NULL, ao2_cleanup);
 
 	ast_debug(1, "Bridge %s: actually destroying %s bridge, nobody wants it anymore\n",
 		bridge->uniqueid, bridge->v_table->name);
 
-	msg = stasis_cache_clear_create(ast_bridge_snapshot_type(), bridge->uniqueid);
-	if (msg) {
-		stasis_publish(ast_bridge_topic(bridge), msg);
+	clear_msg = create_bridge_snapshot_message(bridge);
+	if (clear_msg) {
+		RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
+		msg = stasis_cache_clear_create(clear_msg);
+		if (msg) {
+			stasis_publish(ast_bridge_topic(bridge), msg);
+		}
 	}
 
 	/* Do any pending actions in the context of destruction. */

Modified: trunk/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/channel.c?view=diff&rev=390830&r1=390829&r2=390830
==============================================================================
--- trunk/main/channel.c (original)
+++ trunk/main/channel.c Fri Jun  7 07:56:56 2013
@@ -817,11 +817,28 @@
 	return -1;
 }
 
+static struct stasis_message *create_channel_snapshot_message(struct ast_channel *channel)
+{
+	RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
+	snapshot = ast_channel_snapshot_create(channel);
+	if (!snapshot) {
+		return NULL;
+	}
+
+	return stasis_message_create(ast_channel_snapshot_type(), snapshot);
+}
+
 static void publish_cache_clear(struct ast_channel *chan)
 {
 	RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
-
-	message = stasis_cache_clear_create(ast_channel_snapshot_type(), ast_channel_uniqueid(chan));
+	RAII_VAR(struct stasis_message *, clear_msg, NULL, ao2_cleanup);
+
+	clear_msg = create_channel_snapshot_message(chan);
+	if (!clear_msg) {
+		return;
+	}
+
+	message = stasis_cache_clear_create(clear_msg);
 	stasis_publish(ast_channel_topic(chan), message);
 }
 
@@ -1161,6 +1178,7 @@
 	}
 
 	ast_channel_internal_finalize(tmp);
+	ast_publish_channel_state(tmp);
 	return tmp;
 }
 
@@ -2369,6 +2387,8 @@
 	char device_name[AST_CHANNEL_NAME];
 	struct ast_callid *callid;
 
+	publish_cache_clear(chan);
+
 	if (ast_channel_internal_is_finalized(chan)) {
 		ast_cel_report_event(chan, AST_CEL_CHANNEL_END, NULL, NULL, NULL);
 		ast_cel_check_retire_linkedid(chan);
@@ -2884,7 +2904,6 @@
 	ast_cc_offer(chan);
 
 	ast_publish_channel_state(chan);
-	publish_cache_clear(chan);
 
 	if (ast_channel_cdr(chan) && !ast_test_flag(ast_channel_cdr(chan), AST_CDR_FLAG_BRIDGED) &&
 		!ast_test_flag(ast_channel_cdr(chan), AST_CDR_FLAG_POST_DISABLED) &&

Modified: trunk/main/endpoints.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/endpoints.c?view=diff&rev=390830&r1=390829&r2=390830
==============================================================================
--- trunk/main/endpoints.c (original)
+++ trunk/main/endpoints.c Fri Jun  7 07:56:56 2013
@@ -145,18 +145,25 @@
 	}
 }
 
+/*! \brief Handler for channel snapshot cache clears */
 static void endpoint_cache_clear(void *data,
 	struct stasis_subscription *sub, struct stasis_topic *topic,
 	struct stasis_message *message)
 {
 	struct ast_endpoint *endpoint = data;
-	struct stasis_cache_clear *clear = stasis_message_data(message);
-
-	ast_assert(endpoint != NULL);
-	ast_assert(clear != NULL);
+	struct stasis_message *clear_msg = stasis_message_data(message);
+	struct ast_channel_snapshot *clear_snapshot;
+
+	if (stasis_message_type(clear_msg) != ast_channel_snapshot_type()) {
+		return;
+	}
+
+	clear_snapshot = stasis_message_data(clear_msg);
+
+	ast_assert(endpoint != NULL);
 
 	ao2_lock(endpoint);
-	ao2_find(endpoint->channel_ids, clear->id, OBJ_POINTER | OBJ_NODATA | OBJ_UNLINK);
+	ast_str_container_remove(endpoint->channel_ids, clear_snapshot->uniqueid);
 	ao2_unlock(endpoint);
 	endpoint_publish_snapshot(endpoint);
 }
@@ -247,17 +254,32 @@
 	return endpoint->tech;
 }
 
+static struct stasis_message *create_endpoint_snapshot_message(struct ast_endpoint *endpoint)
+{
+	RAII_VAR(struct ast_endpoint_snapshot *, snapshot, NULL, ao2_cleanup);
+	snapshot = ast_endpoint_snapshot_create(endpoint);
+	if (!snapshot) {
+		return NULL;
+	}
+
+	return stasis_message_create(ast_endpoint_snapshot_type(), snapshot);
+}
+
 void ast_endpoint_shutdown(struct ast_endpoint *endpoint)
 {
-	RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
+	RAII_VAR(struct stasis_message *, clear_msg, NULL, ao2_cleanup);
 
 	if (endpoint == NULL) {
 		return;
 	}
 
-	message = stasis_cache_clear_create(ast_endpoint_snapshot_type(), endpoint->id);
-	if (message) {
-		stasis_publish(endpoint->topic, message);
+	clear_msg = create_endpoint_snapshot_message(endpoint);
+	if (clear_msg) {
+		RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
+		message = stasis_cache_clear_create(clear_msg);
+		if (message) {
+			stasis_publish(endpoint->topic, message);
+		}
 	}
 
 	/* Bump refcount to hold on to the router */

Modified: trunk/main/stasis_cache.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/stasis_cache.c?view=diff&rev=390830&r1=390829&r2=390830
==============================================================================
--- trunk/main/stasis_cache.c (original)
+++ trunk/main/stasis_cache.c Fri Jun  7 07:56:56 2013
@@ -262,30 +262,11 @@
 STASIS_MESSAGE_TYPE_DEFN(stasis_cache_clear_type);
 STASIS_MESSAGE_TYPE_DEFN(stasis_cache_update_type);
 
-static void cache_clear_dtor(void *obj)
-{
-	struct stasis_cache_clear *ev = obj;
-	ao2_cleanup(ev->type);
-	ev->type = NULL;
-}
-
-struct stasis_message *stasis_cache_clear_create(struct stasis_message_type *type, const char *id)
-{
-	RAII_VAR(struct stasis_cache_clear *, ev, NULL, ao2_cleanup);
+struct stasis_message *stasis_cache_clear_create(struct stasis_message *id_message)
+{
 	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
 
-	ev = ao2_alloc(sizeof(*ev) + strlen(id) + 1, cache_clear_dtor);
-	if (!ev) {
-		return NULL;
-	}
-
-	/* strcpy safe */
-	strcpy(ev->id, id);
-	ao2_ref(type, +1);
-	ev->type = type;
-
-	msg = stasis_message_create(stasis_cache_clear_type(), ev);
-
+	msg = stasis_message_create(stasis_cache_clear_type(), id_message);
 	if (!msg) {
 		return NULL;
 	}
@@ -363,21 +344,25 @@
 	if (stasis_cache_clear_type() == stasis_message_type(message)) {
 		RAII_VAR(struct stasis_message *, old_snapshot, NULL, ao2_cleanup);
 		RAII_VAR(struct stasis_message *, update, NULL, ao2_cleanup);
-		struct stasis_cache_clear *clear = stasis_message_data(message);
-		ast_assert(clear->type != NULL);
-		ast_assert(clear->id != NULL);
-		old_snapshot = cache_put(caching_topic, clear->type, clear->id, NULL);
-		if (old_snapshot) {
-			update = update_create(topic, old_snapshot, NULL);
-			stasis_publish(caching_topic->topic, update);
-		} else {
-			/* While this could be a problem, it's very likely to
-			 * happen with message forwarding */
-			ast_debug(1,
-				"Attempting to remove an item from the cache that isn't there: %s %s\n",
-				stasis_message_type_name(clear->type), clear->id);
-		}
-		return;
+		struct stasis_message *clear_msg = stasis_message_data(message);
+		const char *clear_id = caching_topic->id_fn(clear_msg);
+		struct stasis_message_type *clear_type = stasis_message_type(clear_msg);
+
+		ast_assert(clear_type != NULL);
+
+		if (clear_id) {
+			old_snapshot = cache_put(caching_topic, clear_type, clear_id, NULL);
+			if (old_snapshot) {
+				update = update_create(topic, old_snapshot, NULL);
+				stasis_publish(caching_topic->topic, update);
+				return;
+			}
+
+			ast_log(LOG_ERROR,
+				"Attempting to remove an item from the %s cache that isn't there: %s %s\n",
+				stasis_topic_name(caching_topic->topic), stasis_message_type_name(clear_type), clear_id);
+			return;
+		}
 	}
 
 	id = caching_topic->id_fn(message);

Modified: trunk/main/stasis_channels.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/stasis_channels.c?view=diff&rev=390830&r1=390829&r2=390830
==============================================================================
--- trunk/main/stasis_channels.c (original)
+++ trunk/main/stasis_channels.c Fri Jun  7 07:56:56 2013
@@ -131,6 +131,11 @@
 {
 	RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
 
+	/* no snapshots for dummy channels */
+	if (!ast_channel_tech(chan)) {
+		return NULL;
+	}
+
 	snapshot = ao2_alloc(sizeof(*snapshot), channel_snapshot_dtor);
 	if (!snapshot || ast_string_field_init(snapshot, 1024)) {
 		return NULL;

Modified: trunk/tests/test_stasis.c
URL: http://svnview.digium.com/svn/asterisk/trunk/tests/test_stasis.c?view=diff&rev=390830&r1=390829&r2=390830
==============================================================================
--- trunk/tests/test_stasis.c (original)
+++ trunk/tests/test_stasis.c Fri Jun  7 07:56:56 2013
@@ -716,7 +716,7 @@
 	ao2_ref(test_message2_2, -1);
 
 	/* Clear snapshot 1 */
-	test_message1_clear = stasis_cache_clear_create(cache_type, "1");
+	test_message1_clear = stasis_cache_clear_create(test_message1_1);
 	ast_test_validate(test, NULL != test_message1_clear);
 	stasis_publish(topic, test_message1_clear);
 
@@ -811,7 +811,7 @@
 	}
 
 	/* Clear snapshot 1 */
-	test_message1_clear = stasis_cache_clear_create(cache_type, "1");
+	test_message1_clear = stasis_cache_clear_create(test_message1_1);
 	ast_test_validate(test, NULL != test_message1_clear);
 	stasis_publish(topic, test_message1_clear);
 




More information about the asterisk-commits mailing list