From b3bb9564d34f949fcb15025f5d0f7a5d1bb541bc Mon Sep 17 00:00:00 2001 From: Tilghman Lesher Date: Fri, 17 Oct 2008 16:34:29 +0000 Subject: [PATCH] Fix the FRACK! warnings in chan_iax2 when POKE/LAGRQ packets are not answered. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@150580 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_iax2.c | 10 ++++++++-- include/asterisk/sched.h | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index eca3ba7b3f..a477c97fe7 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -1412,6 +1412,8 @@ static int iax2_getpeername(struct sockaddr_in sin, char *host, int len) return res; } +/*!\note Assumes the lock on the pvt is already held, when + * iax2_destroy_helper() is called. */ static void iax2_destroy_helper(struct chan_iax2_pvt *pvt) { /* Decrement AUTHREQ count if needed */ @@ -1430,8 +1432,8 @@ static void iax2_destroy_helper(struct chan_iax2_pvt *pvt) ast_clear_flag(pvt, IAX_MAXAUTHREQ); } /* No more pings or lagrq's */ - AST_SCHED_DEL(sched, pvt->pingid); - AST_SCHED_DEL(sched, pvt->lagid); + AST_SCHED_DEL_SPINLOCK(sched, pvt->pingid, &iaxsl[pvt->callno]); + AST_SCHED_DEL_SPINLOCK(sched, pvt->lagid, &iaxsl[pvt->callno]); AST_SCHED_DEL(sched, pvt->autoid); AST_SCHED_DEL(sched, pvt->authid); AST_SCHED_DEL(sched, pvt->initid); @@ -1450,7 +1452,9 @@ static void pvt_destructor(void *obj) struct chan_iax2_pvt *pvt = obj; struct iax_frame *cur = NULL; + ast_mutex_lock(&iaxsl[pvt->callno]); iax2_destroy_helper(pvt); + ast_mutex_unlock(&iaxsl[pvt->callno]); /* Already gone */ ast_set_flag(pvt, IAX_ALREADYGONE); @@ -2309,6 +2313,8 @@ static void iax2_destroy(int callno) retry: pvt = iaxs[callno]; + iax2_destroy_helper(pvt); + lastused[callno] = ast_tvnow(); owner = pvt ? pvt->owner : NULL; diff --git a/include/asterisk/sched.h b/include/asterisk/sched.h index 993ba6b7eb..92a5d76a49 100644 --- a/include/asterisk/sched.h +++ b/include/asterisk/sched.h @@ -72,6 +72,22 @@ extern "C" { id = -1; \ } while (0); +#define AST_SCHED_DEL_SPINLOCK(sched, id, lock) \ + ({ \ + int _count = 0; \ + int _sched_res = -1; \ + while (id > -1 && (_sched_res = ast_sched_del(sched, id)) && ++_count < 10) { \ + ast_mutex_unlock(lock); \ + usleep(1); \ + ast_mutex_lock(lock); \ + } \ + if (_count == 10 && option_debug > 2) { \ + ast_log(LOG_DEBUG, "Unable to cancel schedule ID %d.\n", id); \ + } \ + id = -1; \ + (_sched_res); \ + }) + #define AST_SCHED_REPLACE_VARIABLE(id, sched, when, callback, data, variable) \ do { \ int _count = 0; \