[asterisk-commits] jpeeler: branch jpeeler/bug12269 r147387 - /team/jpeeler/bug12269/channels/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Oct 7 16:33:57 CDT 2008


Author: jpeeler
Date: Tue Oct  7 16:33:56 2008
New Revision: 147387

URL: http://svn.digium.com/view/asterisk?view=rev&rev=147387
Log:
maybe I didn't need a branch after all, adding a condition variable seems to have done the trick

Modified:
    team/jpeeler/bug12269/channels/chan_agent.c

Modified: team/jpeeler/bug12269/channels/chan_agent.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/bug12269/channels/chan_agent.c?view=diff&rev=147387&r1=147386&r2=147387
==============================================================================
--- team/jpeeler/bug12269/channels/chan_agent.c (original)
+++ team/jpeeler/bug12269/channels/chan_agent.c Tue Oct  7 16:33:56 2008
@@ -195,6 +195,8 @@
 	char name[AST_MAX_AGENT];
 	int inherited_devicestate;     /*!< Does the underlying channel have a devicestate to pass? */
 	ast_mutex_t app_lock;          /**< Synchronization between owning applications */
+	int app_lock_flag;
+	ast_cond_t app_complete_cond;
 	volatile pthread_t owning_app; /**< Owning application thread id */
 	volatile int app_sleep_cond;   /**< Sleep condition for the login app */
 	struct ast_channel *owner;     /**< Agent */
@@ -380,6 +382,8 @@
 		ast_copy_string(p->agent, agt, sizeof(p->agent));
 		ast_mutex_init(&p->lock);
 		ast_mutex_init(&p->app_lock);
+		ast_cond_init(&p->app_complete_cond, NULL);
+		p->app_lock_flag = 0;
 		p->owning_app = (pthread_t) -1;
 		p->app_sleep_cond = 1;
 		p->group = group;
@@ -428,12 +432,16 @@
 	chan->tech_pvt = NULL;
 	p->app_sleep_cond = 1;
 	/* Release ownership of the agent to other threads (presumably running the login app). */
+	ast_mutex_lock(&p->app_lock);
+	p->app_lock_flag = 0;
+	ast_cond_signal(&p->app_complete_cond);
 	ast_mutex_unlock(&p->app_lock);
 	if (chan)
 		ast_channel_free(chan);
 	if (p->dead) {
 		ast_mutex_destroy(&p->lock);
 		ast_mutex_destroy(&p->app_lock);
+		ast_cond_destroy(&p->app_complete_cond);
 		free(p);
         }
 	return 0;
@@ -924,6 +932,7 @@
 	} else if (p->dead) {
 		ast_mutex_destroy(&p->lock);
 		ast_mutex_destroy(&p->app_lock);
+		ast_cond_destroy(&p->app_complete_cond);
 		free(p);
 	} else {
 		if (p->chan) {
@@ -936,6 +945,9 @@
 		/* Release ownership of the agent to other threads (presumably running the login app). */
 		if (ast_strlen_zero(p->loginchan)) {
 ast_log(LOG_NOTICE, "jpeeler: attempting to release app_lock in thread %p with p->owning_app=%p\n", (void *) pthread_self(), (void *) p->owning_app);
+			ast_mutex_lock(&p->app_lock);
+			p->app_lock_flag = 0;
+			ast_cond_signal(&p->app_complete_cond);
 			ast_mutex_unlock(&p->app_lock);
 		}
 	}
@@ -1075,11 +1087,13 @@
 	 * implemented in the kernel for this.
 	 */
 	p->app_sleep_cond = 0;
-	if(ast_strlen_zero(p->loginchan) && ast_mutex_trylock(&p->app_lock)) {
+	if(ast_strlen_zero(p->loginchan) && !p->app_lock_flag) {
 		if (p->chan) {
 			ast_queue_frame(p->chan, &ast_null_frame);
 			ast_mutex_unlock(&p->lock);	/* For other thread to read the condition. */
 			ast_mutex_lock(&p->app_lock);
+			p->app_lock_flag = 1;
+			ast_mutex_unlock(&p->app_lock);
 			ast_mutex_lock(&p->lock);
 		} else {
 			ast_log(LOG_WARNING, "Agent disconnected while we were connecting the call\n");
@@ -1088,6 +1102,9 @@
 			p->app_sleep_cond = 1;
 			ast_channel_free( tmp );
 			ast_mutex_unlock(&p->lock);	/* For other thread to read the condition. */
+			ast_mutex_lock(&p->app_lock);
+			p->app_lock_flag = 0;
+			ast_cond_signal(&p->app_complete_cond);
 			ast_mutex_unlock(&p->app_lock);
 			return NULL;
 		}
@@ -1259,6 +1276,7 @@
 				if (!p->chan) {
 					ast_mutex_destroy(&p->lock);
 					ast_mutex_destroy(&p->app_lock);
+					ast_cond_destroy(&p->app_complete_cond);
 					free(p);
 				} else {
 					/* Cause them to hang up */
@@ -2255,7 +2273,10 @@
 							AST_LIST_UNLOCK(&agents);
 							/*	Synchronize channel ownership between call to agent and itself. */
 ast_log(LOG_NOTICE, "jpeeler: waiting for app_lock\n");
-							ast_mutex_lock( &p->app_lock );
+							ast_mutex_lock(&p->app_lock);
+							if (p->app_lock_flag == 1) {
+								ast_cond_wait(&p->app_complete_cond, &p->app_lock);
+							}
 ast_log(LOG_NOTICE, "jpeeler: app_lock obtained by thread %p\n", (void *) pthread_self());
 							ast_mutex_lock(&p->lock);
 							p->owning_app = pthread_self();
@@ -2264,6 +2285,7 @@
 								res = agent_ack_sleep(p);
 							else
 								res = ast_safe_sleep_conditional( chan, 1000, agent_cont_sleep, p );
+							p->app_lock_flag = 0;
 							ast_mutex_unlock( &p->app_lock );
 ast_log(LOG_NOTICE, "jpeeler: app_lock released by thread %p\n", (void *) pthread_self());
 							if ((p->ackcall > 1)  && (res == 1)) {
@@ -2301,6 +2323,7 @@
 						if (p->dead && !p->owner) {
 							ast_mutex_destroy(&p->lock);
 							ast_mutex_destroy(&p->app_lock);
+							ast_cond_destroy(&p->app_complete_cond);
 							free(p);
 						}
 					}




More information about the asterisk-commits mailing list