[asterisk-commits] russell: branch russell/smdi-1.4 r93091 - /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:16:05 CST 2007


Author: russell
Date: Fri Dec 14 15:16:04 2007
New Revision: 93091

URL: http://svn.digium.com/view/asterisk?view=rev&rev=93091
Log:
When waiting for a message to arrive in the md_q, 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=93091&r1=93090&r2=93091
==============================================================================
--- team/russell/smdi-1.4/res/res_smdi.c (original)
+++ team/russell/smdi-1.4/res/res_smdi.c Fri Dec 14 15:16:04 2007
@@ -67,6 +67,8 @@
 struct ast_smdi_interface {
 	ASTOBJ_COMPONENTS_FULL(struct ast_smdi_interface, SMDI_MAX_FILENAME_LEN, 1);
 	struct ast_smdi_md_queue md_q;
+	ast_mutex_t md_q_lock;
+	ast_cond_t md_q_cond;
 	struct ast_smdi_mwi_queue mwi_q;
 	FILE *file;
 	int fd;
@@ -133,7 +135,10 @@
  */
 static void ast_smdi_md_message_push(struct ast_smdi_interface *iface, struct ast_smdi_md_message *md_msg)
 {
+	ast_mutex_lock(&iface->md_q_lock);
 	ASTOBJ_CONTAINER_LINK_END(&iface->md_q, md_msg);
+	ast_cond_broadcast(&iface->md_q_cond);
+	ast_mutex_unlock(&iface->md_q_lock);
 }
 
 /*!
@@ -220,7 +225,10 @@
  */
 void ast_smdi_md_message_putback(struct ast_smdi_interface *iface, struct ast_smdi_md_message *md_msg)
 {
+	ast_mutex_lock(&iface->md_q_lock);
 	ASTOBJ_CONTAINER_LINK_START(&iface->md_q, md_msg);
+	ast_cond_broadcast(&iface->md_q_cond);
+	ast_mutex_unlock(&iface->md_q_lock);
 }
 
 /*!
@@ -249,9 +257,13 @@
  */
 struct ast_smdi_md_message *ast_smdi_md_message_pop(struct ast_smdi_interface *iface)
 {
-	struct ast_smdi_md_message *md_msg = ASTOBJ_CONTAINER_UNLINK_START(&iface->md_q);
+	struct ast_smdi_md_message *md_msg;
 	struct timeval now;
 	long elapsed = 0;
+
+	ast_mutex_lock(&iface->md_q_lock);
+	md_msg = ASTOBJ_CONTAINER_UNLINK_START(&iface->md_q);
+	ast_mutex_unlock(&iface->md_q_lock);
 
 	/* purge old messages */
 	now = ast_tvnow();
@@ -263,7 +275,10 @@
 			ASTOBJ_UNREF(md_msg, ast_smdi_md_message_destroy);
 			ast_log(LOG_NOTICE, "Purged expired message from %s SMDI MD message queue.  Message was %ld milliseconds too old.\n",
 				iface->name, elapsed - iface->msg_expiry);
+
+			ast_mutex_lock(&iface->md_q_lock);
 			md_msg = ASTOBJ_CONTAINER_UNLINK_START(&iface->md_q);
+			ast_mutex_unlock(&iface->md_q_lock);
 		}
 		else {
 			/* good message, return it */
@@ -294,13 +309,37 @@
 
 	start = ast_tvnow();
 	while (diff < timeout) {
-
-		if ((msg = ast_smdi_md_message_pop(iface)))
+		struct timespec ts = { 0, };
+		struct timeval tv;
+
+		ast_mutex_lock(&iface->md_q_lock);
+
+		if ((msg = ast_smdi_md_message_pop(iface))) {
+			ast_mutex_unlock(&iface->md_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->md_q_cond, &iface->md_q_lock);
+
+		if ((msg = ast_smdi_md_message_pop(iface))) {
+			ast_mutex_unlock(&iface->md_q_lock);
+			return msg;
+		}
+	
+		ast_mutex_unlock(&iface->md_q_lock);
 
 		/* check timeout */
 		diff = ast_tvdiff_ms(ast_tvnow(), start);
 	}
+
+	/* A timeout occurred, but try one last time ... */
 
 	return (ast_smdi_md_message_pop(iface));
 }
@@ -561,6 +600,10 @@
 	ASTOBJ_CONTAINER_DESTROYALL(&iface->mwi_q, ast_smdi_mwi_message_destroy);
 	ASTOBJ_CONTAINER_DESTROY(&iface->md_q);
 	ASTOBJ_CONTAINER_DESTROY(&iface->mwi_q);
+
+	ast_mutex_destroy(&iface->md_q_lock);
+	ast_cond_destroy(&iface->md_q_cond);
+
 	free(iface);
 
 	ast_module_unref(ast_module_info->self);
@@ -782,6 +825,9 @@
 			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));
 
 			if (!(iface->file = fopen(iface->name, "r"))) {




More information about the asterisk-commits mailing list