[asterisk-commits] mmichelson: branch mmichelson/pub_sub r385165 - /team/mmichelson/pub_sub/res/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Apr 9 17:46:30 CDT 2013


Author: mmichelson
Date: Tue Apr  9 17:46:27 2013
New Revision: 385165

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=385165
Log:
Restructure objects to more accurately reflect what is necessary.

This also fills in some of the missing container allocations and does isolates
some logic to their own functions.


Modified:
    team/mmichelson/pub_sub/res/res_sip_mwi.c

Modified: team/mmichelson/pub_sub/res/res_sip_mwi.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pub_sub/res/res_sip_mwi.c?view=diff&rev=385165&r1=385164&r2=385165
==============================================================================
--- team/mmichelson/pub_sub/res/res_sip_mwi.c (original)
+++ team/mmichelson/pub_sub/res/res_sip_mwi.c Tue Apr  9 17:46:27 2013
@@ -37,6 +37,72 @@
 	<depend>res_sip_pubsub</depend>
 	<support_level>core</support_level>
  ***/
+
+struct ao2_container *mwi_subscriptions;
+
+#define STASIS_BUCKETS 13
+#define MWI_BUCKETS 53
+
+struct mwi_stasis_subscription {
+	struct stasis_subscription *stasis_sub;
+	char mailbox[1];
+};
+
+static void mwi_stasis_subscription_destructor(void *obj)
+{
+	struct mwi_stasis_subscription *mwi_stasis = obj;
+
+	if (mwi_stasis->stasis_sub) {
+		mwi_stasis->stasis_sub = stasis_unsubscribe(mwi_stasis->stasis_sub);
+	}
+}
+
+static int stasis_sub_hash(const void *obj, int flags)
+{
+	const struct mwi_stasis_subscription *mwi_stasis = obj;
+
+	return ast_str_hash(mwi_stasis->mailbox);
+}
+
+static int stasis_sub_cmp(void *obj, void *arg, int flags)
+{
+	struct mwi_stasis_subscription *mwi_stasis1 = obj;
+	struct mwi_stasis_subscription *mwi_stasis2 = arg;
+
+	return strcmp(mwi_stasis1->mailbox, mwi_stasis2->mailbox) ? 0 : CMP_MATCH;
+}
+
+struct mwi_subscription {
+	struct ao2_container *stasis_subs;
+	struct ast_sip_subscription *sip_sub;
+	char id[1];
+};
+
+static void mwi_subscription_destructor(void *obj)
+{
+	struct mwi_subscription *sub = obj;
+	ao2_cleanup(sub->sip_sub);
+	ao2_cleanup(sub->stasis_subs);
+}
+
+static int mwi_sub_hash(const void *obj, int flags)
+{
+	const struct mwi_subscription *mwi_sub = obj;
+	
+	return ast_str_hash(mwi_sub->id);
+}
+
+static int mwi_sub_cmp(void *obj, void *arg, int flags)
+{
+	struct mwi_subscription *mwi_sub1 = obj;
+	struct mwi_subscription *mwi_sub2 = arg;
+
+	return strcmp(mwi_sub1->id, mwi_sub2->id) ? 0 : CMP_MATCH;
+}
+
+static void send_mwi_notify(struct mwi_subscription *sub)
+{
+}
 
 static void mwi_subscription_shutdown(struct ast_sip_subscription *sub)
 {
@@ -98,25 +164,6 @@
 	.refresh_subscription = mwi_refresh_subscription,
 };
 
-struct ao2_container *mwi_subscriptions;
-
-struct mwi_subscription {
-	const char *id;
-	struct stasis_subscription *event_sub;
-	struct ast_sip_subscription *sip_sub;
-};
-
-static void mwi_subscription_destructor(void *obj)
-{
-	struct mwi_subscription *sub = obj;
-	ao2_cleanup(sub->sip_sub);
-	ast_free((char *)sub->id);
-}
-
-static void send_mwi_notify(struct ast_sip_subscription *sub)
-{
-}
-
 static void mwi_stasis_cb(void *userdata, struct stasis_subscription *sub,
 		struct stasis_topic *topic, struct stasis_message *msg)
 {
@@ -126,33 +173,75 @@
 		return;
 	}
 	if (stasis_mwi_state_type() == stasis_message_type(msg)) {
-		send_mwi_notify(mwi_sub->sip_sub);
-	}
+		send_mwi_notify(mwi_sub);
+	}
+}
+
+static struct mwi_subscription *mwi_subscription_alloc(struct ast_sip_endpoint *endpoint)
+{
+	struct mwi_subscription *sub;
+	const char *endpoint_id = ast_sorcery_object_get_id(endpoint);
+
+	sub = ao2_alloc(sizeof(*sub) + strlen(endpoint_id),
+			mwi_subscription_destructor);
+
+	if (!sub) {
+		return NULL;
+	}
+
+	/* Safe strcpy */
+	strcpy(sub->id, endpoint_id);
+	/* MWI is an interesting case because the NOTIFYs we send are
+	 * unsolicited. We get around the requirement of needing an
+	 * incoming SUBSCRIBE by pretending that we are the subscriber
+	 */
+	sub->sip_sub = ast_sip_create_subscription(&mwi_handler,
+			AST_SIP_SUBSCRIBER, endpoint, NULL);
+	if (!sub->sip_sub) {
+		ao2_cleanup(sub);
+		return NULL;
+	}
+
+	sub->stasis_subs = ao2_container_alloc(STASIS_BUCKETS, stasis_sub_hash, stasis_sub_cmp);
+	if (!sub->stasis_subs) {
+		ao2_cleanup(sub);
+		return NULL;
+	}
+
+	return sub;
 }
 
 static int create_mwi_subscriptions_for_endpoint(void *obj, void *arg, int flags)
 {
+	RAII_VAR(struct mwi_subscription *, sub, NULL, ao2_cleanup);
 	struct ast_sip_endpoint *endpoint = obj;
-	char *mailboxes = ast_strdupa(endpoint->mailboxes);
+	char *mailboxes;
 	char *mailbox;
 
+	if (ast_strlen_zero(endpoint->mailboxes)) {
+		return 0;
+	}
+
+	sub = mwi_subscription_alloc(endpoint);
+	if (!sub) {
+		return 0;
+	}
+
+	mailboxes = ast_strdupa(endpoint->mailboxes);
 	while ((mailbox = strsep(&mailboxes, ","))) {
-		struct mwi_subscription *sub;
+		RAII_VAR(struct mwi_stasis_subscription *, mwi_stasis_sub,
+				ao2_alloc(sizeof(*mwi_stasis_sub) + strlen(mailbox),
+					mwi_stasis_subscription_destructor), ao2_cleanup);
 		struct stasis_topic *topic;
 
 		topic = stasis_mwi_topic(mailbox);
-			
-		sub = ao2_alloc(sizeof(*sub), mwi_subscription_destructor);
-		sub->id = ast_strdup(ast_sorcery_object_get_id(endpoint));
-		/* MWI is an interesting case because the NOTIFYs we send are
-		 * unsolicited. We get around the requirement of needing an
-		 * incoming SUBSCRIBE by pretending that we are the subscriber
-		 */
-		sub->sip_sub = ast_sip_create_subscription(&mwi_handler,
-				AST_SIP_SUBSCRIBER, endpoint, NULL);
-		sub->event_sub = stasis_subscribe(topic, mwi_stasis_cb, sub);
-		ao2_link(mwi_subscriptions, sub);
-	}
+
+		/* Safe strcpy */
+		strcpy(mwi_stasis_sub->mailbox, mailbox);
+		mwi_stasis_sub->stasis_sub = stasis_subscribe(topic, mwi_stasis_cb, sub);
+		ao2_link(sub->stasis_subs, mwi_stasis_sub);
+	}
+	ao2_link(mwi_subscriptions, sub);
 	return 0;
 }
 
@@ -169,6 +258,10 @@
 {
 	if (ast_sip_register_subscription_handler(&mwi_handler)) {
 		return AST_MODULE_LOAD_DECLINE;
+	}
+	mwi_subscriptions = ao2_container_alloc(MWI_BUCKETS, mwi_sub_hash, mwi_sub_cmp);
+	if (!mwi_subscriptions) {
+		ast_sip_unregister_subscription_handler(&mwi_handler);
 	}
 	create_mwi_subscriptions();
 	return AST_MODULE_LOAD_SUCCESS;




More information about the asterisk-commits mailing list