diff options
author | file <file@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-11-01 18:21:34 +0000 |
---|---|---|
committer | file <file@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-11-01 18:21:34 +0000 |
commit | 424f792d1f1028ef441a88282e0354b7dd264a7c (patch) | |
tree | 8a914d839880a119a2922848a7d22eacbf3d6022 | |
parent | 1afcf53b160d80f7e7f7691326e7347a7e92ab87 (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.c | 36 |
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); } |