[Asterisk-cvs] asterisk/channels chan_h323.c,1.122,1.123
jeremy at lists.digium.com
jeremy at lists.digium.com
Wed Jul 27 00:38:36 CDT 2005
Update of /usr/cvsroot/asterisk/channels
In directory mongoose.digium.com:/tmp/cvs-serv26348
Modified Files:
chan_h323.c
Log Message:
Stomp on deadlock. Bug #4555
Index: chan_h323.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_h323.c,v
retrieving revision 1.122
retrieving revision 1.123
diff -u -d -r1.122 -r1.123
--- chan_h323.c 27 Jul 2005 04:39:53 -0000 1.122
+++ chan_h323.c 27 Jul 2005 04:45:11 -0000 1.123
@@ -140,7 +140,9 @@
int nativeformats; /* Codec formats supported by a channel */
int needhangup; /* Send hangup when Asterisk is ready */
int hangupcause; /* Hangup cause from OpenH323 layer */
- struct oh323_pvt *next; /* Next channel in list */
+ int newstate; /* Pending state change */
+ int newcontrol; /* Pending control to send */
+ struct oh323_pvt *next; /* Next channel in list */
} *iflist = NULL;
static struct ast_user_list {
@@ -233,6 +235,15 @@
c->hangupcause = pvt->hangupcause;
ast_queue_hangup(c);
pvt->needhangup = 0;
+ pvt->newstate = pvt->newcontrol = -1;
+ }
+ if (pvt->newstate >= 0) {
+ ast_setstate(c, pvt->newstate);
+ pvt->newstate = -1;
+ }
+ if (pvt->newcontrol >= 0) {
+ ast_queue_control(c, pvt->newcontrol);
+ pvt->newcontrol = -1;
}
}
@@ -550,18 +561,22 @@
}
/* Do in-band DTMF detection */
if ((pvt->options.dtmfmode & H323_DTMF_INBAND) && pvt->vad) {
- f = ast_dsp_process(pvt->owner,pvt->vad,f);
+ if (!ast_mutex_trylock(&pvt->owner->lock)) {
+ f = ast_dsp_process(pvt->owner,pvt->vad,f);
+ ast_mutex_unlock(&pvt->owner->lock);
+ }
+ else
+ ast_log(LOG_NOTICE, "Unable to process inband DTMF while channel is locked\n");
if (f &&(f->frametype == AST_FRAME_DTMF)) {
ast_log(LOG_DEBUG, "Received in-band digit %c.\n", f->subclass);
- }
+ }
}
-
}
}
return f;
}
-static struct ast_frame *oh323_read(struct ast_channel *c)
+static struct ast_frame *oh323_read(struct ast_channel *c)
{
struct ast_frame *fr;
struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt;
@@ -595,6 +610,7 @@
if (pvt->rtp) {
res = ast_rtp_write(pvt->rtp, frame);
}
+ __oh323_update_info(c, pvt);
ast_mutex_unlock(&pvt->lock);
}
return res;
@@ -807,6 +823,7 @@
pvt->nonCodecCapability &= ~AST_RTP_DTMF;
}
strncpy(pvt->context, default_context, sizeof(pvt->context) - 1);
+ pvt->newstate = pvt->newsignal = -1;
/* Add to interface list */
ast_mutex_lock(&iflock);
pvt->next = iflist;
@@ -841,6 +858,26 @@
return NULL;
}
+static int update_state(struct oh323_pvt *pvt, int state, int signal)
+{
+ if (!pvt)
+ return 0;
+ if (pvt->owner && !ast_mutex_trylock(&pvt->owner->lock)) {
+ if (state >= 0)
+ ast_setstate(pvt->owner, state);
+ if (signal >= 0)
+ ast_queue_control(pvt->owner, signal);
+ return 1;
+ }
+ else {
+ if (state >= 0)
+ pvt->newstate = state;
+ if (signal >= 0)
+ pvt->newsignal = signal;
+ return 0;
+ }
+}
+
struct oh323_user *find_user(const call_details_t *cd)
{
struct oh323_user *u;
@@ -1116,8 +1153,6 @@
return info;
}
-int progress(unsigned call_reference, const char *token, int inband);
-
/**
* Definition taken from rtp.c for rtpPayloadType because we need it here.
*/
@@ -1156,10 +1191,16 @@
pvt->owner->nativeformats = pvt->nativeformats;
ast_set_read_format(pvt->owner, pvt->owner->readformat);
ast_set_write_format(pvt->owner, pvt->owner->writeformat);
+ if (pvt->options.progress_audio)
+ ast_queue_control(pvt->owner, AST_CONTROL_PROGRESS);
ast_mutex_unlock(&pvt->owner->lock);
}
- else if (h323debug)
- ast_log(LOG_DEBUG, "RTP connection preparation for %s is pending...\n", token);
+ else {
+ if (pvt->options.progress_audio)
+ pvt->newcontrol = AST_CONTROL_PROGRESS;
+ if (h323debug)
+ ast_log(LOG_DEBUG, "RTP connection preparation for %s is pending...\n", token);
+ }
them.sin_family = AF_INET;
/* only works for IPv4 */
@@ -1167,11 +1208,7 @@
them.sin_port = htons(remotePort);
ast_rtp_set_peer(pvt->rtp, &them);
- if (pvt->options.progress_audio) {
- ast_mutex_unlock(&pvt->lock);
- progress(call_reference, token, 1);
- } else
- ast_mutex_unlock(&pvt->lock);
+ ast_mutex_unlock(&pvt->lock);
if (h323debug)
ast_log(LOG_DEBUG, "RTP connection prepared for %s\n", token);
@@ -1202,16 +1239,8 @@
ast_mutex_unlock(&pvt->lock);
return;
}
- if (!pvt->owner) {
- ast_mutex_unlock(&pvt->lock);
- ast_log(LOG_ERROR, "Channel has no owner\n");
- return;
- }
- ast_mutex_lock(&pvt->owner->lock);
- c = pvt->owner;
- ast_setstate(c, AST_STATE_UP);
- ast_queue_control(c, AST_CONTROL_ANSWER);
- ast_mutex_unlock(&pvt->owner->lock);
+ if (update_state(pvt, AST_STATE_UP, AST_CONTROL_ANSWER))
+ ast_mutex_unlock(&pvt->owner->lock);
ast_mutex_unlock(&pvt->lock);
return;
}
@@ -1232,9 +1261,8 @@
ast_log(LOG_ERROR, "No Asterisk channel associated with private structure.\n");
return -1;
}
- ast_mutex_lock(&pvt->owner->lock);
- ast_queue_control(pvt->owner, (inband ? AST_CONTROL_PROGRESS : AST_CONTROL_RINGING));
- ast_mutex_unlock(&pvt->owner->lock);
+ if (update_state(pvt, -1, (inband ? AST_CONTROL_PROGRESS : AST_CONTROL_RINGING)))
+ ast_mutex_unlock(&pvt->owner->lock);
ast_mutex_unlock(&pvt->lock);
return 0;
@@ -1402,20 +1430,18 @@
if (h323debug)
ast_log(LOG_DEBUG, "Ringing on %s\n", token);
- pvt = find_call_locked(call_reference, token);
- if (!pvt) {
- ast_log(LOG_ERROR, "Something is wrong: ringing\n");
+ pvt = find_call_locked(call_reference, token);
+ if (!pvt) {
+ ast_log(LOG_ERROR, "Something is wrong: ringing\n");
+ return;
}
if (!pvt->owner) {
ast_mutex_unlock(&pvt->lock);
ast_log(LOG_ERROR, "Channel has no owner\n");
return;
}
- ast_mutex_lock(&pvt->owner->lock);
- c = pvt->owner;
- ast_setstate(c, AST_STATE_RINGING);
- ast_queue_control(c, AST_CONTROL_RINGING);
- ast_mutex_unlock(&pvt->owner->lock);
+ if (update_state(pvt, AST_STATE_RINGING, AST_CONTROL_RINGING))
+ ast_mutex_unlock(&pvt->owner->lock);
ast_mutex_unlock(&pvt->lock);
return;
}
More information about the svn-commits
mailing list