[asterisk-commits] russell: branch russell/smdi-1.4 r93092 - /team/russell/smdi-1.4/res/res_smdi.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Dec 14 15:25:54 CST 2007


Author: russell
Date: Fri Dec 14 15:25:53 2007
New Revision: 93092

URL: http://svn.digium.com/view/asterisk?view=rev&rev=93092
Log:
when waiting for an mwi smdi message, don't wait in a busy loop

Modified:
    team/russell/smdi-1.4/res/res_smdi.c

Modified: team/russell/smdi-1.4/res/res_smdi.c
URL: http://svn.digium.com/view/asterisk/team/russell/smdi-1.4/res/res_smdi.c?view=diff&rev=93092&r1=93091&r2=93092
==============================================================================
--- team/russell/smdi-1.4/res/res_smdi.c (original)
+++ team/russell/smdi-1.4/res/res_smdi.c Fri Dec 14 15:25:53 2007
@@ -70,6 +70,8 @@
 	ast_mutex_t md_q_lock;
 	ast_cond_t md_q_cond;
 	struct ast_smdi_mwi_queue mwi_q;
+	ast_mutex_t mwi_q_lock;
+	ast_cond_t mwi_q_cond;
 	FILE *file;
 	int fd;
 	pthread_t thread;
@@ -149,7 +151,10 @@
  */
 static void ast_smdi_mwi_message_push(struct ast_smdi_interface *iface, struct ast_smdi_mwi_message *mwi_msg)
 {
+	ast_mutex_lock(&iface->mwi_q_lock);
 	ASTOBJ_CONTAINER_LINK_END(&iface->mwi_q, mwi_msg);
+	ast_cond_broadcast(&iface->md_q_cond);
+	ast_mutex_unlock(&iface->mwi_q_lock);
 }
 
 /*!
@@ -242,7 +247,10 @@
  */
 void ast_smdi_mwi_message_putback(struct ast_smdi_interface *iface, struct ast_smdi_mwi_message *mwi_msg)
 {
+	ast_mutex_lock(&iface->mwi_q_lock);
 	ASTOBJ_CONTAINER_LINK_START(&iface->mwi_q, mwi_msg);
+	ast_cond_broadcast(&iface->mwi_q_cond);
+	ast_mutex_unlock(&iface->mwi_q_lock);
 }
 
 /*! 
@@ -356,9 +364,13 @@
  */
 extern struct ast_smdi_mwi_message *ast_smdi_mwi_message_pop(struct ast_smdi_interface *iface)
 {
-	struct ast_smdi_mwi_message *mwi_msg = ASTOBJ_CONTAINER_UNLINK_START(&iface->mwi_q);
+	struct ast_smdi_mwi_message *mwi_msg;
 	struct timeval now;
 	long elapsed = 0;
+
+	ast_mutex_lock(&iface->mwi_q_lock);
+	mwi_msg = ASTOBJ_CONTAINER_UNLINK_START(&iface->mwi_q);
+	ast_mutex_unlock(&iface->mwi_q_lock);
 
 	/* purge old messages */
 	now = ast_tvnow();
@@ -370,7 +382,10 @@
 			ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy);
 			ast_log(LOG_NOTICE, "Purged expired message from %s SMDI MWI message queue.  Message was %ld milliseconds too old.\n",
 				iface->name, elapsed - iface->msg_expiry);
+
+			ast_mutex_lock(&iface->mwi_q_lock);
 			mwi_msg = ASTOBJ_CONTAINER_UNLINK_START(&iface->mwi_q);
+			ast_mutex_unlock(&iface->mwi_q_lock);
 		}
 		else {
 			/* good message, return it */
@@ -401,13 +416,37 @@
 
 	start = ast_tvnow();
 	while (diff < timeout) {
-
-		if ((msg = ast_smdi_mwi_message_pop(iface)))
+		struct timespec ts = { 0, };
+		struct timeval tv;
+
+		ast_mutex_lock(&iface->mwi_q_lock);
+
+		if ((msg = ast_smdi_mwi_message_pop(iface))) {
+			ast_mutex_unlock(&iface->mwi_q_lock);
 			return msg;
+		}
+
+		tv = ast_tvadd(start, ast_tv(0, timeout));
+		ts.tv_sec = tv.tv_sec;
+		ts.tv_nsec = tv.tv_usec * 1000;
+
+		/* If there were no messages in the queue, then go to sleep until one
+		 * arrives. */
+
+		ast_cond_wait(&iface->mwi_q_cond, &iface->mwi_q_lock);
+
+		if ((msg = ast_smdi_mwi_message_pop(iface))) {
+			ast_mutex_unlock(&iface->mwi_q_lock);
+			return msg;
+		}
+
+		ast_mutex_unlock(&iface->mwi_q_lock);
 
 		/* check timeout */
 		diff = ast_tvdiff_ms(ast_tvnow(), start);
 	}
+
+	/* A timeout occurred, but try one last time ... */
 
 	return (ast_smdi_mwi_message_pop(iface));
 }
@@ -604,6 +643,9 @@
 	ast_mutex_destroy(&iface->md_q_lock);
 	ast_cond_destroy(&iface->md_q_cond);
 
+	ast_mutex_destroy(&iface->mwi_q_lock);
+	ast_cond_destroy(&iface->mwi_q_cond);
+
 	free(iface);
 
 	ast_module_unref(ast_module_info->self);
@@ -703,6 +745,26 @@
 	}
 
 	return NULL;
+}
+
+static struct ast_smdi_interface *alloc_smdi_interface(void)
+{
+	struct ast_smdi_interface *iface;
+
+	if (!(iface = ast_calloc(1, sizeof(*iface))))
+		return NULL;
+
+	ASTOBJ_INIT(iface);
+	ASTOBJ_CONTAINER_INIT(&iface->md_q);
+	ASTOBJ_CONTAINER_INIT(&iface->mwi_q);
+
+	ast_mutex_init(&iface->md_q_lock);
+	ast_cond_init(&iface->md_q_cond, NULL);
+
+	ast_mutex_init(&iface->mwi_q_lock);
+	ast_cond_init(&iface->mwi_q_cond, NULL);
+
+	return iface;
 }
 
 /*!
@@ -817,16 +879,9 @@
 					continue;
 				}
 			}
-							
-			if (!(iface = ast_calloc(1, sizeof(*iface))))
+			
+			if (!(iface = alloc_smdi_interface()))
 				continue;
-
-			ASTOBJ_INIT(iface);
-			ASTOBJ_CONTAINER_INIT(&iface->md_q);
-			ASTOBJ_CONTAINER_INIT(&iface->mwi_q);
-
-			ast_mutex_init(&iface->md_q_lock);
-			ast_cond_init(&iface->md_q_cond, NULL);
 
 			ast_copy_string(iface->name, v->value, sizeof(iface->name));
 




More information about the asterisk-commits mailing list