[asterisk-commits] jpeeler: branch 1.6.1 r168510 - in /branches/1.6.1: ./ channels/chan_agent.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Jan 12 15:02:32 CST 2009


Author: jpeeler
Date: Mon Jan 12 15:02:32 2009
New Revision: 168510

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=168510
Log:
Merged revisions 168508 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

................
  r168508 | jpeeler | 2009-01-12 14:53:04 -0600 (Mon, 12 Jan 2009) | 15 lines
  
  Merged revisions 168507 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.4
  
  ........
    r168507 | jpeeler | 2009-01-12 14:26:22 -0600 (Mon, 12 Jan 2009) | 9 lines
    
    (closes issue #12269)
    Reported by: IgorG
    Tested by: denisgalvao
    
    This gits rid of the notion of an owning_app allowing the request and hangup to be initiated by different threads. Originating from an active agent channel requires this. The implementation primarily changes __login_exec to wait on a condition variable rather than a lock.
    
    Review: http://reviewboard.digium.com/r/35/
  ........
................

Modified:
    branches/1.6.1/   (props changed)
    branches/1.6.1/channels/chan_agent.c

Propchange: branches/1.6.1/
------------------------------------------------------------------------------
Binary property 'trunk-merged' - no diff available.

Modified: branches/1.6.1/channels/chan_agent.c
URL: http://svn.digium.com/svn-view/asterisk/branches/1.6.1/channels/chan_agent.c?view=diff&rev=168510&r1=168509&r2=168510
==============================================================================
--- branches/1.6.1/channels/chan_agent.c (original)
+++ branches/1.6.1/channels/chan_agent.c Mon Jan 12 15:02:32 2009
@@ -183,7 +183,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 */
-	volatile pthread_t owning_app; /**< Owning application thread id */
+	int app_lock_flag;
+	ast_cond_t app_complete_cond;
 	volatile int app_sleep_cond;   /**< Sleep condition for the login app */
 	struct ast_channel *owner;     /**< Agent */
 	char loginchan[80];            /**< channel they logged in from */
@@ -378,7 +379,8 @@
 		ast_copy_string(p->agent, agt, sizeof(p->agent));
 		ast_mutex_init(&p->lock);
 		ast_mutex_init(&p->app_lock);
-		p->owning_app = (pthread_t) -1;
+		ast_cond_init(&p->app_complete_cond, NULL);
+		p->app_lock_flag = 0;
 		p->app_sleep_cond = 1;
 		p->group = group;
 		p->pending = pending;
@@ -436,12 +438,14 @@
 	chan->tech_pvt = NULL;
 	p->app_sleep_cond = 1;
 	/* Release ownership of the agent to other threads (presumably running the login app). */
-	ast_mutex_unlock(&p->app_lock);
+	p->app_lock_flag = 0;
+	ast_cond_signal(&p->app_complete_cond);
 	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);
 		ast_free(p);
         }
 	return 0;
@@ -928,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);
 		ast_free(p);
 	} else {
 		if (p->chan) {
@@ -938,8 +943,10 @@
 			ast_mutex_unlock(&p->lock);
 		}
 		/* Release ownership of the agent to other threads (presumably running the login app). */
-		if (ast_strlen_zero(p->loginchan))
-			ast_mutex_unlock(&p->app_lock);
+		if (ast_strlen_zero(p->loginchan)) {
+			p->app_lock_flag = 0;
+			ast_cond_signal(&p->app_complete_cond);
+		}
 	}
 	return 0;
 }
@@ -1026,6 +1033,7 @@
 static struct ast_channel *agent_new(struct agent_pvt *p, int state)
 {
 	struct ast_channel *tmp;
+	int alreadylocked;
 #if 0
 	if (!p->chan) {
 		ast_log(LOG_WARNING, "No channel? :(\n");
@@ -1071,11 +1079,15 @@
 	 * implemented in the kernel for this.
 	 */
 	p->app_sleep_cond = 0;
-	if(ast_strlen_zero(p->loginchan) && ast_mutex_trylock(&p->app_lock)) {
+
+	alreadylocked = p->app_lock_flag;
+	p->app_lock_flag = 1;
+
+	if(ast_strlen_zero(p->loginchan) && alreadylocked) {
 		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_lock(&p->lock);
 		} else {
 			ast_log(LOG_WARNING, "Agent disconnected while we were connecting the call\n");
@@ -1084,7 +1096,8 @@
 			p->app_sleep_cond = 1;
 			ast_channel_free( tmp );
 			ast_mutex_unlock(&p->lock);	/* For other thread to read the condition. */
-			ast_mutex_unlock(&p->app_lock);
+			p->app_lock_flag = 0;
+			ast_cond_signal(&p->app_complete_cond);
 			return NULL;
 		}
 	} else if (!ast_strlen_zero(p->loginchan)) {
@@ -1102,14 +1115,6 @@
 	} 
 	if (p->chan)
 		ast_indicate(p->chan, AST_CONTROL_UNHOLD);
-	p->owning_app = pthread_self();
-	/* After the above step, there should not be any blockers. */
-	if (p->chan) {
-		if (ast_test_flag(p->chan, AST_FLAG_BLOCKING)) {
-			ast_log( LOG_ERROR, "A blocker exists after agent channel ownership acquired\n" );
-			ast_assert(ast_test_flag(p->chan, AST_FLAG_BLOCKING) == 0);
-		}
-	}
 	return tmp;
 }
 
@@ -1261,6 +1266,7 @@
 				if (!p->chan) {
 					ast_mutex_destroy(&p->lock);
 					ast_mutex_destroy(&p->app_lock);
+					ast_cond_destroy(&p->app_complete_cond);
 					ast_free(p);
 				} else {
 					/* Cause them to hang up */
@@ -2147,15 +2153,17 @@
 							ast_mutex_unlock(&p->lock);
 							AST_LIST_UNLOCK(&agents);
 							/*	Synchronize channel ownership between call to agent and itself. */
-							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_mutex_unlock(&p->app_lock);
 							ast_mutex_lock(&p->lock);
-							p->owning_app = pthread_self();
 							ast_mutex_unlock(&p->lock);
 							if (p->ackcall > 1) 
 								res = agent_ack_sleep(p);
 							else
 								res = ast_safe_sleep_conditional( chan, 1000, agent_cont_sleep, p );
-							ast_mutex_unlock( &p->app_lock );
 							if ((p->ackcall > 1)  && (res == 1)) {
 								AST_LIST_LOCK(&agents);
 								ast_mutex_lock(&p->lock);
@@ -2190,6 +2198,7 @@
 						if (p->dead && !p->owner) {
 							ast_mutex_destroy(&p->lock);
 							ast_mutex_destroy(&p->app_lock);
+							ast_cond_destroy(&p->app_complete_cond);
 							ast_free(p);
 						}
 					}




More information about the asterisk-commits mailing list