From b2f1e7f70ab4ccba0bc50ead5c4de020ecfe7d4e Mon Sep 17 00:00:00 2001 From: Andreas Granig Date: Wed, 15 Feb 2012 15:38:00 +0000 Subject: [PATCH] Some more fixes when deleting calls. --- daemon/call.c | 46 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/daemon/call.c b/daemon/call.c index 23ab388c3..51b6d8b73 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -76,14 +76,12 @@ static char *rtp_codecs[] = { static void call_destroy(struct call *); +static void call_destory_all_branches(struct call *); static void unkernelize(struct peer *); - - - static void stream_closed(int fd, void *p) { struct streamrelay *r = p; struct call *c; @@ -92,7 +90,7 @@ static void stream_closed(int fd, void *p) { mylog(LOG_WARNING, "[%s] Read error on RTP socket", c->callid); - call_destroy(c); + call_destroy_all_branches(c); } @@ -343,7 +341,7 @@ err: if (stream_packet(r, buf, ret, sinp)) { mylog(LOG_WARNING, "Write error on RTP socket"); - call_destroy(r->up->up->call); + call_destroy_all_branches(r->up->up->call); return; } } @@ -533,9 +531,11 @@ next: for (i = hlp.del; i; i = n) { n = i->next; c = i->data; - if(c->prev) - c->prev->next = c->next; - call_destroy(c); + if(!c->prev && !$c->next) { + call_destroy_all_branches(c); + } else { + call_destroy(c); + } g_list_free_1(i); } } @@ -1099,19 +1099,42 @@ static void kill_callstream(struct callstream *s) { g_slice_free1(sizeof(*s), s); } +static void call_destroy_all_branches(struct call *c) { + struct callmaster *m = c->callmaster; + struct call *next; + /* rewind to beginning of list */ + for(c; c->prev; c = c->prev); + + /* delete full list */ + while(c) { + mylog(LOG_INFO, "[%s - %s] Delete call branch", + c->callid, c->viabranch ? c->viabranch : ""); + if(!c->next) { + /* delete hash entry when on last branch */ + g_hash_table_remove(m->callhash, c->callid); + } + next = c->next; + call_destroy(c); + c = next; + } +} static void call_destroy(struct call *c) { struct callmaster *m = c->callmaster; struct callstream *s; - g_hash_table_remove(m->callhash, c->callid); + if(c->prev) + c->prev->next = c->next; + #ifndef NO_REDIS - /* TODO: take into account the viabranch */ + /* TODO: take into account the viabranch list */ redis_delete(c); #endif free(c->callid); + if(c->viabranch) + free(c->viabranch); g_hash_table_destroy(c->infohash); if (c->calling_agent) free(c->calling_agent); @@ -1414,6 +1437,9 @@ char *call_delete_udp(const char **out, struct callmaster *m) { if (!c) goto err; + DBG("got delete for callid '%s' and viabranch '%s'", + out[RE_UDP_D_CALLID], out[RE_UDP_D_VIABRANCH] ? out[RE_UDP_D_VIABRANCH] : ""); + if(out[RE_UDP_D_VIABRANCH]) { /* only delete selective branch */ while(c) {