[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