aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfile <file@f38db490-d61c-443f-a65b-d21fe96a405b>2006-11-01 18:21:34 +0000
committerfile <file@f38db490-d61c-443f-a65b-d21fe96a405b>2006-11-01 18:21:34 +0000
commit424f792d1f1028ef441a88282e0354b7dd264a7c (patch)
tree8a914d839880a119a2922848a7d22eacbf3d6022
parent1afcf53b160d80f7e7f7691326e7347a7e92ab87 (diff)
It's another round of chan_iax2 fixes! Should hopefully fix the deadlock issues people have been reporting. IAXtel now has qualify turned on for 800 peers and it is handling it fine.
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.4@46775 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--channels/chan_iax2.c36
1 files changed, 18 insertions, 18 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index e51ccafc7..642dd6d61 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -4957,18 +4957,10 @@ static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *
ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
return -1;
}
- /* We release the lock for the call to prevent a deadlock, but it's okay because
- only the current thread could possibly make it go away or make changes */
- ast_mutex_unlock(&iaxsl[callno]);
+
/* SLD: first call to lookup peer during registration */
p = find_peer(peer, 1);
- ast_mutex_lock(&iaxsl[callno]);
- if (!iaxs[callno]) {
- /* Call has disappeared */
- ast_mutex_unlock(&iaxsl[callno]);
- return -1;
- }
if (!p) {
if (authdebug)
ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
@@ -5620,6 +5612,11 @@ static int update_registry(const char *name, struct sockaddr_in *sin, int callno
/* Verify that the host is really there */
iax2_poke_peer(p, callno);
}
+
+ /* Make sure our call still exists, an INVAL at the right point may make it go away */
+ if (!iaxs[callno])
+ return 0;
+
/* Store socket fd */
p->sockfd = fd;
/* Setup the expiry */
@@ -8059,13 +8056,19 @@ static void *network_thread(void *ignore)
if (f->sentyet)
continue;
+ /* Try to lock the pvt, if we can't... don't fret - defer it till later */
+ if (ast_mutex_trylock(&iaxsl[f->callno]))
+ continue;
+
f->sentyet++;
- ast_mutex_lock(&iaxsl[f->callno]);
+
if (iaxs[f->callno]) {
send_packet(f);
count++;
}
+
ast_mutex_unlock(&iaxsl[f->callno]);
+
if (f->retries < 0) {
/* This is not supposed to be retransmitted */
AST_LIST_REMOVE(&iaxq.queue, f, list);
@@ -8717,15 +8720,8 @@ static void prune_users(void)
static void destroy_peer(struct iax2_peer *peer)
{
- int x;
ast_free_ha(peer->ha);
- for (x=0;x<IAX_MAX_CALLS;x++) {
- ast_mutex_lock(&iaxsl[x]);
- if (iaxs[x] && (iaxs[x]->peerpoke == peer)) {
- iax2_destroy(x);
- }
- ast_mutex_unlock(&iaxsl[x]);
- }
+
/* Delete it, it needs to disappear */
if (peer->expire > -1)
ast_sched_del(sched, peer->expire);
@@ -8733,10 +8729,14 @@ static void destroy_peer(struct iax2_peer *peer)
ast_sched_del(sched, peer->pokeexpire);
if (peer->callno > 0)
iax2_destroy(peer->callno);
+
register_peer_exten(peer, 0);
+
if (peer->dnsmgr)
ast_dnsmgr_release(peer->dnsmgr);
+
ast_string_field_free_pools(peer);
+
free(peer);
}