Fix the FRACK! warnings in chan_iax2 when POKE/LAGRQ packets are not answered.
authorTilghman Lesher <tilghman@meg.abyt.es>
Fri, 17 Oct 2008 16:34:29 +0000 (16:34 +0000)
committerTilghman Lesher <tilghman@meg.abyt.es>
Fri, 17 Oct 2008 16:34:29 +0000 (16:34 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@150580 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_iax2.c
include/asterisk/sched.h

index eca3ba7..a477c97 100644 (file)
@@ -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;
index 993ba6b..92a5d76 100644 (file)
@@ -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; \