Index: pbx/pbx_dundi.c =================================================================== --- pbx/pbx_dundi.c (revision 98969) +++ pbx/pbx_dundi.c (working copy) @@ -1658,8 +1658,8 @@ int expire = default_expiration; char data[256]; int needqual = 0; - if (peer->registerexpire > -1) - ast_sched_del(sched, peer->registerexpire); + while (peer->registerexpire > -1 && ast_sched_del(sched, peer->registerexpire)) + usleep(1); peer->registerexpire = ast_sched_add(sched, (expire + 10) * 1000, do_register_expire, peer); snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(trans->addr.sin_addr), ntohs(trans->addr.sin_port), expire); @@ -1945,8 +1945,8 @@ struct dundi_packet *pack; while ((pack = AST_LIST_REMOVE_HEAD(p, list))) { - if (pack->retransid > -1) - ast_sched_del(sched, pack->retransid); + while (pack->retransid > -1 && ast_sched_del(sched, pack->retransid)) + usleep(1); free(pack); } } @@ -1965,8 +1965,8 @@ destroy_packets(&trans->lasttrans); } AST_LIST_INSERT_HEAD(&trans->lasttrans, pack, list); - if (trans->autokillid > -1) - ast_sched_del(sched, trans->autokillid); + while (trans->autokillid > -1 && ast_sched_del(sched, trans->autokillid)) + usleep(1); trans->autokillid = -1; return 1; } @@ -2861,8 +2861,8 @@ { if (pack->parent) AST_LIST_REMOVE(&pack->parent->packets, pack, list); - if (pack->retransid > -1) - ast_sched_del(sched, pack->retransid); + while (pack->retransid > -1 && ast_sched_del(sched, pack->retransid)) + usleep(1); if (needfree) free(pack); else @@ -2942,8 +2942,8 @@ AST_LIST_REMOVE(&alltrans, trans, all); destroy_packets(&trans->packets); destroy_packets(&trans->lasttrans); - if (trans->autokillid > -1) - ast_sched_del(sched, trans->autokillid); + while (trans->autokillid > -1 && ast_sched_del(sched, trans->autokillid)) + usleep(1); trans->autokillid = -1; if (trans->thread) { /* If used by a thread, mark as dead and be done */ @@ -3889,12 +3889,12 @@ static void destroy_peer(struct dundi_peer *peer) { - if (peer->registerid > -1) - ast_sched_del(sched, peer->registerid); + while (peer->registerid > -1 && ast_sched_del(sched, peer->registerid)) + usleep(1); if (peer->regtrans) destroy_trans(peer->regtrans, 0); - if (peer->qualifyid > -1) - ast_sched_del(sched, peer->qualifyid); + while (peer->qualifyid > -1 && ast_sched_del(sched, peer->qualifyid)) + usleep(1); destroy_permissions(&peer->permit); destroy_permissions(&peer->include); free(peer); @@ -4057,8 +4057,8 @@ static void qualify_peer(struct dundi_peer *peer, int schedonly) { int when; - if (peer->qualifyid > -1) - ast_sched_del(sched, peer->qualifyid); + while (peer->qualifyid > -1 && ast_sched_del(sched, peer->qualifyid)) + usleep(1); peer->qualifyid = -1; if (peer->qualtrans) destroy_trans(peer->qualtrans, 0); @@ -4137,8 +4137,8 @@ peer->us_eid = global_eid; destroy_permissions(&peer->permit); destroy_permissions(&peer->include); - if (peer->registerid > -1) - ast_sched_del(sched, peer->registerid); + while (peer->registerid > -1 && ast_sched_del(sched, peer->registerid)) + usleep(1); peer->registerid = -1; for (; v; v = v->next) { if (!strcasecmp(v->name, "inkey")) { Index: channels/chan_misdn.c =================================================================== --- channels/chan_misdn.c (revision 98969) +++ channels/chan_misdn.c (working copy) @@ -639,7 +639,8 @@ static void misdn_tasks_remove (int task_id) { - ast_sched_del(misdn_tasks, task_id); + while (ast_sched_del(misdn_tasks, task_id)) + usleep(1); } static int misdn_l1_task (const void *data) Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 98969) +++ channels/chan_sip.c (working copy) @@ -1267,7 +1267,7 @@ int useglobal_nat, const int intended_method); static int __sip_autodestruct(const void *data); static void sip_scheddestroy(struct sip_pvt *p, int ms); -static void sip_cancel_destroy(struct sip_pvt *p); +static int sip_cancel_destroy(struct sip_pvt *p); static void sip_destroy(struct sip_pvt *p); static void __sip_destroy(struct sip_pvt *p, int lockowner); static void __sip_ack(struct sip_pvt *p, int seqno, int resp, int sipmethod); @@ -2035,10 +2035,9 @@ if (pkt->timer_t1) siptimer_a = pkt->timer_t1 * 2; - /* Schedule retransmission */ - pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); if (option_debug > 3 && sipdebug) ast_log(LOG_DEBUG, "*** SIP TIMER: Initializing retransmit timer on packet: Id #%d\n", pkt->retransid); + pkt->retransid = -1; pkt->next = p->packets; p->packets = pkt; if (sipmethod == SIP_INVITE) { @@ -2050,11 +2049,12 @@ if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); - ast_sched_del(sched, pkt->retransid); /* No more retransmission */ - pkt->retransid = -1; return AST_FAILURE; - } else + } else { + /* Schedule retransmission */ + pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); return AST_SUCCESS; + } } /*! \brief Kill a SIP dialog (called by scheduler) */ @@ -2116,19 +2116,22 @@ if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) append_history(p, "SchedDestroy", "%d ms", ms); - if (p->autokillid > -1) - ast_sched_del(sched, p->autokillid); + while (p->autokillid > -1 && ast_sched_del(sched, p->autokillid)) + usleep(1); p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); } /*! \brief Cancel destruction of SIP dialog */ -static void sip_cancel_destroy(struct sip_pvt *p) +static int sip_cancel_destroy(struct sip_pvt *p) { + int res = 0; if (p->autokillid > -1) { - ast_sched_del(sched, p->autokillid); - append_history(p, "CancelDestroy", ""); - p->autokillid = -1; + if (!(res = ast_sched_del(sched, p->autokillid))) { + append_history(p, "CancelDestroy", ""); + p->autokillid = -1; + } } + return res; } /*! \brief Acknowledges receipt of a packet and stops retransmission */ @@ -2158,9 +2161,10 @@ if (cur->retransid > -1) { if (sipdebug && option_debug > 3) ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); - ast_sched_del(sched, cur->retransid); - cur->retransid = -1; } + while (cur->retransid > -1 && ast_sched_del(sched, cur->retransid)) + usleep(1); + cur->retransid = -1; free(cur); break; } @@ -2201,9 +2205,10 @@ if (cur->retransid > -1) { if (option_debug > 3 && sipdebug) ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); - ast_sched_del(sched, cur->retransid); - cur->retransid = -1; } + while (cur->retransid > -1 && ast_sched_del(sched, cur->retransid)) + usleep(1); + cur->retransid = -1; res = 0; break; } @@ -2459,8 +2464,10 @@ */ while (peer->expire > -1 && ast_sched_del(sched, peer->expire)) usleep(1); + peer->expire = -1; while (peer->pokeexpire > -1 && ast_sched_del(sched, peer->pokeexpire)) usleep(1); + peer->pokeexpire = -1; register_peer_exten(peer, FALSE); ast_free_ha(peer->ha); @@ -2614,9 +2621,8 @@ /* Cache peer */ ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { - if (peer->expire > -1) { - ast_sched_del(sched, peer->expire); - } + while (peer->expire > -1 && ast_sched_del(sched, peer->expire)) + usleep(1); peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, (void *)peer); } ASTOBJ_CONTAINER_LINK(&peerl,peer); @@ -3018,8 +3024,8 @@ p->invitestate = INV_CALLING; /* Initialize auto-congest time */ - if (p->initid > -1) - ast_sched_del(sched, p->initid); + while (p->initid > -1 && ast_sched_del(sched, p->initid)) + usleep(1); p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p); } } @@ -3042,10 +3048,10 @@ ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); sip_destroy(reg->call); } - if (reg->expire > -1) - ast_sched_del(sched, reg->expire); - if (reg->timeout > -1) - ast_sched_del(sched, reg->timeout); + while (reg->expire > -1 && ast_sched_del(sched, reg->expire)) + usleep(1); + while (reg->timeout > -1 && ast_sched_del(sched, reg->timeout)) + usleep(1); ast_string_field_free_memory(reg); regobjs--; free(reg); @@ -3079,12 +3085,12 @@ if (p->stateid > -1) ast_extension_state_del(p->stateid, NULL); - if (p->initid > -1) - ast_sched_del(sched, p->initid); - if (p->waitid > -1) - ast_sched_del(sched, p->waitid); - if (p->autokillid > -1) - ast_sched_del(sched, p->autokillid); + while (p->initid > -1 && ast_sched_del(sched, p->initid)) + usleep(1); + while (p->waitid > -1 && ast_sched_del(sched, p->waitid)) + usleep(1); + while (p->autokillid > -1 && ast_sched_del(sched, p->autokillid)) + usleep(1); if (p->rtp) ast_rtp_destroy(p->rtp); @@ -3139,8 +3145,8 @@ /* remove all current packets in this dialog */ while((cp = p->packets)) { p->packets = p->packets->next; - if (cp->retransid > -1) - ast_sched_del(sched, cp->retransid); + while (cp->retransid > -1 && ast_sched_del(sched, cp->retransid)) + usleep(1); free(cp); } if (p->chanvars) { @@ -3475,8 +3481,8 @@ } if (option_debug >3) ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); - if (p->autokillid > -1) - sip_cancel_destroy(p); + if (p->autokillid > -1 && sip_cancel_destroy(p)) + ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY); @@ -3602,10 +3608,11 @@ but we can't send one while we have "INVITE" outstanding. */ ast_set_flag(&p->flags[0], SIP_PENDINGBYE); ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); - if (p->waitid) - ast_sched_del(sched, p->waitid); + while (p->waitid > -1 && ast_sched_del(sched, p->waitid)) + usleep(1); p->waitid = -1; - sip_cancel_destroy(p); + if (sip_cancel_destroy(p)) + ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); } } } @@ -7501,14 +7508,15 @@ /* we have what we hope is a temporary network error, * probably DNS. We need to reschedule a registration try */ sip_destroy(p); - if (r->timeout > -1) { - ast_sched_del(sched, r->timeout); - r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); + + if (r->timeout > -1) ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); - } else { - r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); + else ast_log(LOG_WARNING, "Probably a DNS error for registration to %s@%s, trying REGISTER again (after %d seconds)\n", r->username, r->hostname, global_reg_timeout); - } + + while (r->timeout > -1 && ast_sched_del(sched, r->timeout)) + usleep(1); + r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); r->regattempts++; return 0; } @@ -7553,10 +7561,10 @@ /* set up a timeout */ if (auth == NULL) { - if (r->timeout > -1) { + if (r->timeout > -1) ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); - ast_sched_del(sched, r->timeout); - } + while (r->timeout > -1 && ast_sched_del(sched, r->timeout)) + usleep(1); r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); if (option_debug) ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); @@ -7910,8 +7918,8 @@ peer->addr.sin_port = htons(port); if (sipsock < 0) { /* SIP isn't up yet, so schedule a poke only, pretty soon */ - if (peer->pokeexpire > -1) - ast_sched_del(sched, peer->pokeexpire); + while (peer->pokeexpire > -1 && ast_sched_del(sched, peer->pokeexpire)) + usleep(1); peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, peer); } else sip_poke_peer(peer); @@ -8052,8 +8060,8 @@ } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */ /* This means remove all registrations and return OK */ memset(&peer->addr, 0, sizeof(peer->addr)); - if (peer->expire > -1) - ast_sched_del(sched, peer->expire); + while (peer->expire > -1 && ast_sched_del(sched, peer->expire)) + usleep(1); peer->expire = -1; destroy_association(peer); @@ -8119,10 +8127,9 @@ if (curi && ast_strlen_zero(peer->username)) ast_copy_string(peer->username, curi, sizeof(peer->username)); - if (peer->expire > -1) { - ast_sched_del(sched, peer->expire); - peer->expire = -1; - } + while (peer->expire > -1 && ast_sched_del(sched, peer->expire)) + usleep(1); + peer->expire = -1; if (expiry > max_expiry) expiry = max_expiry; if (expiry < min_expiry) @@ -8487,8 +8494,8 @@ switch(state) { case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ case AST_EXTENSION_REMOVED: /* Extension is gone */ - if (p->autokillid > -1) - sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ + if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ + ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ ast_verbose(VERBOSE_PREFIX_2 "Extension state: Watcher for hint %s %s. Notify User %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", p->username); p->stateid = -1; @@ -8593,7 +8600,8 @@ ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT); transmit_response(p, "100 Trying", req); if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) { - sip_cancel_destroy(p); + if (sip_cancel_destroy(p)) + ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); /* We have a succesful registration attemp with proper authentication, now, update the peer */ @@ -8626,7 +8634,8 @@ peer = temp_peer(name); if (peer) { ASTOBJ_CONTAINER_LINK(&peerl, peer); - sip_cancel_destroy(p); + if (sip_cancel_destroy(p)) + ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); switch (parse_register_contact(p, peer, req)) { case PARSE_REGISTER_FAILED: ast_log(LOG_WARNING, "Failed to parse contact info\n"); @@ -9361,7 +9370,8 @@ do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ); if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { - sip_cancel_destroy(p); + if (sip_cancel_destroy(p)) + ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); /* Copy SIP extensions profile from INVITE */ @@ -12000,11 +12010,10 @@ } /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ - if (p->initid > -1) { - /* Don't auto congest anymore since we've gotten something useful back */ - ast_sched_del(sched, p->initid); - p->initid = -1; - } + /* Don't auto congest anymore since we've gotten something useful back */ + while (p->initid > -1 && ast_sched_del(sched, p->initid)) + usleep(1); + p->initid = -1; /* RFC3261 says we must treat every 1xx response (but not 100) that we don't recognize as if it was 183. @@ -12024,15 +12033,15 @@ switch (resp) { case 100: /* Trying */ case 101: /* Dialog establishment */ - if (!ast_test_flag(req, SIP_PKT_IGNORE)) - sip_cancel_destroy(p); + if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) + ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); check_pendings(p); break; case 180: /* 180 Ringing */ case 182: /* 182 Queued */ - if (!ast_test_flag(req, SIP_PKT_IGNORE)) - sip_cancel_destroy(p); + if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) + ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { ast_queue_control(p->owner, AST_CONTROL_RINGING); if (p->owner->_state != AST_STATE_UP) { @@ -12051,8 +12060,8 @@ break; case 183: /* Session progress */ - if (!ast_test_flag(req, SIP_PKT_IGNORE)) - sip_cancel_destroy(p); + if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) + ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); /* Ignore 183 Session progress without SDP */ if (find_sdp(req)) { p->invitestate = INV_EARLY_MEDIA; @@ -12066,8 +12075,8 @@ break; case 200: /* 200 OK on invite - someone's answering our call */ - if (!ast_test_flag(req, SIP_PKT_IGNORE)) - sip_cancel_destroy(p); + if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) + ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); p->authtries = 0; if (find_sdp(req)) { if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE)) @@ -12389,7 +12398,8 @@ ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); if (global_regattempts_max) p->registry->regattempts = global_regattempts_max+1; - ast_sched_del(sched, r->timeout); + while (r->timeout > -1 && ast_sched_del(sched, r->timeout)) + usleep(1); r->timeout = -1; ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); break; @@ -12399,7 +12409,8 @@ p->registry->regattempts = global_regattempts_max+1; ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); r->call = NULL; - ast_sched_del(sched, r->timeout); + while (r->timeout > -1 && ast_sched_del(sched, r->timeout)) + usleep(1); r->timeout = -1; break; case 407: /* Proxy auth */ @@ -12413,7 +12424,8 @@ p->registry->regattempts = global_regattempts_max+1; ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); r->call = NULL; - ast_sched_del(sched, r->timeout); + while (r->timeout > -1 && ast_sched_del(sched, r->timeout)) + usleep(1); r->timeout = -1; break; case 479: /* SER: Not able to process the URI - address is wrong in register*/ @@ -12422,7 +12434,8 @@ p->registry->regattempts = global_regattempts_max+1; ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); r->call = NULL; - ast_sched_del(sched, r->timeout); + while (r->timeout > -1 && ast_sched_del(sched, r->timeout)) + usleep(1); r->timeout = -1; break; case 200: /* 200 OK */ @@ -12441,9 +12454,10 @@ if (r->timeout > -1) { if (option_debug) ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); - ast_sched_del(sched, r->timeout); } - r->timeout=-1; + while (r->timeout > -1 && ast_sched_del(sched, r->timeout)) + usleep(1); + r->timeout = -1; r->call = NULL; p->registry = NULL; /* Let this one hang around until we have all the responses */ @@ -12452,8 +12466,8 @@ /* set us up for re-registering */ /* figure out how long we got registered for */ - if (r->expire > -1) - ast_sched_del(sched, r->expire); + while (r->expire > -1 && ast_sched_del(sched, r->expire)) + usleep(1); /* according to section 6.13 of RFC, contact headers override expires headers, so check those first */ expires = 0; @@ -12497,8 +12511,8 @@ r->refresh= (int) expires_ms / 1000; /* Schedule re-registration before we expire */ - if (r->expire > -1) - ast_sched_del(sched, r->expire); + while (r->expire > -1 && ast_sched_del(sched, r->expire)) + usleep(1); r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); ASTOBJ_UNREF(r, sip_registry_destroy); } @@ -12542,8 +12556,8 @@ peer->name, s, pingtime); } - if (peer->pokeexpire > -1) - ast_sched_del(sched, peer->pokeexpire); + while (peer->pokeexpire > -1 && ast_sched_del(sched, peer->pokeexpire)) + usleep(1); ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Try again eventually */ @@ -12840,8 +12854,8 @@ ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); } else if ((resp >= 100) && (resp < 200)) { if (sipmethod == SIP_INVITE) { - if (!ast_test_flag(req, SIP_PKT_IGNORE)) - sip_cancel_destroy(p); + if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) + ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); if (find_sdp(req)) process_sdp(p, req); if (p->owner) { @@ -12945,8 +12959,8 @@ default: /* Errors without handlers */ if ((resp >= 100) && (resp < 200)) { if (sipmethod == SIP_INVITE) { /* re-invite */ - if (!ast_test_flag(req, SIP_PKT_IGNORE)) - sip_cancel_destroy(p); + if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) + ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); } } if ((resp >= 300) && (resp < 700)) { @@ -12959,9 +12973,9 @@ case 503: /* Service Unavailable */ case 504: /* Server timeout */ - if (sipmethod == SIP_INVITE) { /* re-invite failed */ - sip_cancel_destroy(p); - } + /* re-invite failed */ + if (sipmethod == SIP_INVITE && sip_cancel_destroy(p)) + ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); break; } } @@ -13760,7 +13774,8 @@ if (!ast_test_flag(req, SIP_PKT_IGNORE)) { int newcall = (p->initreq.headers ? TRUE : FALSE); - sip_cancel_destroy(p); + if (sip_cancel_destroy(p)) + ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); /* This also counts as a pending invite */ p->pendinginvite = seqno; check_via(p, req); @@ -14969,8 +14984,8 @@ else ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); } - if (p->autokillid > -1) - sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ + if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ + ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); if (p->expiry > 0) sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ @@ -15684,8 +15699,8 @@ peer->lastms = -1; ast_device_state_changed("SIP/%s", peer->name); /* Try again quickly */ - if (peer->pokeexpire > -1) - ast_sched_del(sched, peer->pokeexpire); + while (peer->pokeexpire > -1 && ast_sched_del(sched, peer->pokeexpire)) + usleep(1); peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); return 0; } @@ -15701,8 +15716,8 @@ if (!peer->maxms || !peer->addr.sin_addr.s_addr) { /* IF we have no IP, or this isn't to be monitored, return imeediately after clearing things out */ - if (peer->pokeexpire > -1) - ast_sched_del(sched, peer->pokeexpire); + while (peer->pokeexpire > -1 && ast_sched_del(sched, peer->pokeexpire)) + usleep(1); peer->lastms = 0; peer->pokeexpire = -1; peer->call = NULL; @@ -15736,8 +15751,9 @@ build_via(p); build_callid_pvt(p); - if (peer->pokeexpire > -1) - ast_sched_del(sched, peer->pokeexpire); + while (peer->pokeexpire > -1 && ast_sched_del(sched, peer->pokeexpire)) + usleep(1); + peer->pokeexpire = -1; p->relatedpeer = peer; ast_set_flag(&p->flags[0], SIP_OUTGOING); #ifdef VOCAL_DATA_HACK @@ -15750,8 +15766,8 @@ if (xmitres == XMIT_ERROR) sip_poke_noanswer(peer); /* Immediately unreachable, network problems */ else { - if (peer->pokeexpire > -1) - ast_sched_del(sched, peer->pokeexpire); + while (peer->pokeexpire > -1 && ast_sched_del(sched, peer->pokeexpire)) + usleep(1); peer->pokeexpire = ast_sched_add(sched, peer->maxms * 2, sip_poke_noanswer, peer); } @@ -16553,8 +16569,8 @@ } } else { /* Non-dynamic. Make sure we become that way if we're not */ - if (peer->expire > -1) - ast_sched_del(sched, peer->expire); + while (peer->expire > -1 && ast_sched_del(sched, peer->expire)) + usleep(1); peer->expire = -1; ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { @@ -17726,8 +17742,8 @@ ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { ASTOBJ_WRLOCK(iterator); - if (iterator->pokeexpire > -1) - ast_sched_del(sched, iterator->pokeexpire); + while (iterator->pokeexpire > -1 && ast_sched_del(sched, iterator->pokeexpire)) + usleep(1); ms += 100; iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, iterator); ASTOBJ_UNLOCK(iterator); @@ -17748,8 +17764,8 @@ ms = regspacing; ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { ASTOBJ_WRLOCK(iterator); - if (iterator->expire > -1) - ast_sched_del(sched, iterator->expire); + while (iterator->expire > -1 && ast_sched_del(sched, iterator->expire)) + usleep(1); ms += regspacing; iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); ASTOBJ_UNLOCK(iterator); Index: channels/chan_iax2.c =================================================================== --- channels/chan_iax2.c (revision 98969) +++ channels/chan_iax2.c (working copy) @@ -1015,7 +1015,7 @@ int callno = (long)data; /* Ping only if it's real not if it's bridged */ ast_mutex_lock(&iaxsl[callno]); - if (iaxs[callno] && iaxs[callno]->lagid != -1) { + if (iaxs[callno] && iaxs[callno]->lagid > -1) { send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); } @@ -1306,10 +1306,10 @@ iaxs[x]->callno = x; iaxs[callno] = NULL; /* Update the two timers that should have been started */ - if (iaxs[x]->pingid > -1) - ast_sched_del(sched, iaxs[x]->pingid); - if (iaxs[x]->lagid > -1) - ast_sched_del(sched, iaxs[x]->lagid); + while (iaxs[x]->pingid > -1 && ast_sched_del(sched, iaxs[x]->pingid)) + usleep(1); + while (iaxs[x]->lagid > -1 && ast_sched_del(sched, iaxs[x]->lagid)) + usleep(1); iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); if (locked) @@ -1421,8 +1421,8 @@ static void iax2_frame_free(struct iax_frame *fr) { - if (fr->retrans > -1) - ast_sched_del(sched, fr->retrans); + while (fr->retrans > -1 && ast_sched_del(sched, fr->retrans)) + usleep(1); iax_frame_free(fr); } @@ -1892,6 +1892,7 @@ static void iax2_destroy_helper(struct chan_iax2_pvt *pvt) { + int count = 0; /* Decrement AUTHREQ count if needed */ if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { struct iax2_user *user; @@ -1908,23 +1909,23 @@ ast_clear_flag(pvt, IAX_MAXAUTHREQ); } /* No more pings or lagrq's */ - if (pvt->pingid > -1) - ast_sched_del(sched, pvt->pingid); + while (pvt->pingid > -1 && ast_sched_del(sched, pvt->pingid)) + usleep(1); pvt->pingid = -1; - if (pvt->lagid > -1) - ast_sched_del(sched, pvt->lagid); + while (pvt->lagid > -1 && ast_sched_del(sched, pvt->lagid) && count++ < 10) + usleep(1); pvt->lagid = -1; - if (pvt->autoid > -1) - ast_sched_del(sched, pvt->autoid); + while (pvt->autoid > -1 && ast_sched_del(sched, pvt->autoid)) + usleep(1); pvt->autoid = -1; - if (pvt->authid > -1) - ast_sched_del(sched, pvt->authid); + while (pvt->authid > -1 && ast_sched_del(sched, pvt->authid)) + usleep(1); pvt->authid = -1; - if (pvt->initid > -1) - ast_sched_del(sched, pvt->initid); + while (pvt->initid > -1 && ast_sched_del(sched, pvt->initid)) + usleep(1); pvt->initid = -1; - if (pvt->jbid > -1) - ast_sched_del(sched, pvt->jbid); + while (pvt->jbid > -1 && ast_sched_del(sched, pvt->jbid)) + usleep(1); pvt->jbid = -1; } @@ -2422,9 +2423,10 @@ when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); when = jb_next(pvt->jb) - when; - - if(pvt->jbid > -1) ast_sched_del(sched, pvt->jbid); - + + while (pvt->jbid > -1 && ast_sched_del(sched, pvt->jbid)) + usleep(1); + if(when <= 0) { /* XXX should really just empty until when > 0.. */ when = 1; @@ -2579,8 +2581,8 @@ jb_reset(iaxs[fr->callno]->jb); - if (iaxs[fr->callno]->jbid > -1) - ast_sched_del(sched, iaxs[fr->callno]->jbid); + while (iaxs[fr->callno]->jbid > -1 && ast_sched_del(sched, iaxs[fr->callno]->jbid)) + usleep(1); iaxs[fr->callno]->jbid = -1; @@ -5741,8 +5743,8 @@ we are registering to */ reg->refresh = refresh; - if (reg->expire > -1) - ast_sched_del(sched, reg->expire); + while (reg->expire > -1 && ast_sched_del(sched, reg->expire)) + usleep(1); reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { if (option_verbose > 2) { @@ -6203,8 +6205,8 @@ if (iaxs[callno]) { iaxs[callno]->authfail = failcode; if (delayreject) { - if (iaxs[callno]->authid > -1) - ast_sched_del(sched, iaxs[callno]->authid); + while (iaxs[callno]->authid > -1 && ast_sched_del(sched, iaxs[callno]->authid)) + usleep(1); iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno); } else auth_reject((void *)(long)callno); @@ -6246,8 +6248,8 @@ { struct iax_ie_data ied; /* Auto-hangup with 30 seconds of inactivity */ - if (iaxs[callno]->autoid > -1) - ast_sched_del(sched, iaxs[callno]->autoid); + while (iaxs[callno]->autoid > -1 && ast_sched_del(sched, iaxs[callno]->autoid)) + usleep(1); iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno); memset(&ied, 0, sizeof(ied)); iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); @@ -7229,11 +7231,9 @@ } } if (f.frametype == AST_FRAME_IAX) { - if (iaxs[fr->callno]->initid > -1) { - /* Don't auto congest anymore since we've gotten something usefulb ack */ - ast_sched_del(sched, iaxs[fr->callno]->initid); - iaxs[fr->callno]->initid = -1; - } + while (iaxs[fr->callno]->initid > -1 && ast_sched_del(sched, iaxs[fr->callno]->initid)) + usleep(1); + iaxs[fr->callno]->initid = -1; /* Handle the IAX pseudo frame itself */ if (option_debug && iaxdebug) ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass); @@ -8436,8 +8436,8 @@ if (option_debug && iaxdebug) ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username); /* Setup the next registration attempt */ - if (reg->expire > -1) - ast_sched_del(sched, reg->expire); + while (reg->expire > -1 && ast_sched_del(sched, reg->expire)) + usleep(1); reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); return -1; } @@ -8454,8 +8454,8 @@ iaxs[reg->callno]->reg = reg; } /* Schedule the next registration attempt */ - if (reg->expire > -1) - ast_sched_del(sched, reg->expire); + while (reg->expire > -1 && ast_sched_del(sched, reg->expire)) + usleep(1); /* Setup the next registration a little early */ reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); /* Send the request */ @@ -8513,8 +8513,8 @@ ast_mutex_lock(&iaxsl[callno]); if (iaxs[callno]) { /* Schedule autodestruct in case they don't ever give us anything back */ - if (iaxs[callno]->autoid > -1) - ast_sched_del(sched, iaxs[callno]->autoid); + while (iaxs[callno]->autoid > -1 && ast_sched_del(sched, iaxs[callno]->autoid)) + usleep(1); iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno); ast_set_flag(iaxs[callno], IAX_PROVISION); /* Got a call number now, so go ahead and send the provisioning information */ @@ -9160,8 +9160,8 @@ } } else { /* Non-dynamic. Make sure we become that way if we're not */ - if (peer->expire > -1) - ast_sched_del(sched, peer->expire); + while (peer->expire > -1 && ast_sched_del(sched, peer->expire)) + usleep(1); peer->expire = -1; ast_clear_flag(peer, IAX_DYNAMIC); if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) @@ -9531,8 +9531,9 @@ AST_LIST_LOCK(®istrations); while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { - if (reg->expire > -1) - ast_sched_del(sched, reg->expire); + while (reg->expire > -1 && ast_sched_del(sched, reg->expire)) + usleep(1); + reg->expire = -1; if (reg->callno) { ast_mutex_lock(&iaxsl[reg->callno]); if (iaxs[reg->callno]) { Index: main/cdr.c =================================================================== --- main/cdr.c (revision 98969) +++ main/cdr.c (working copy) @@ -1146,8 +1146,8 @@ static void submit_unscheduled_batch(void) { /* this is okay since we are not being called from within the scheduler */ - if (cdr_sched > -1) - ast_sched_del(sched, cdr_sched); + while (cdr_sched > -1 && ast_sched_del(sched, cdr_sched)) + usleep(1); /* schedule the submission to occur ASAP (1 ms) */ cdr_sched = ast_sched_add(sched, 1, submit_scheduled_batch, NULL); /* signal the do_cdr thread to wakeup early and do some work (that lazy thread ;) */ @@ -1328,8 +1328,8 @@ batchmode = 0; /* don't run the next scheduled CDR posting while reloading */ - if (cdr_sched > -1) - ast_sched_del(sched, cdr_sched); + while (cdr_sched > -1 && ast_sched_del(sched, cdr_sched)) + usleep(1); if ((config = ast_config_load("cdr.conf"))) { if ((enabled_value = ast_variable_retrieve(config, "general", "enable"))) { @@ -1382,7 +1382,9 @@ ast_cond_init(&cdr_pending_cond, NULL); if (ast_pthread_create_background(&cdr_thread, NULL, do_cdr, NULL) < 0) { ast_log(LOG_ERROR, "Unable to start CDR thread.\n"); - ast_sched_del(sched, cdr_sched); + while (cdr_sched > -1 && ast_sched_del(sched, cdr_sched)) + usleep(1); + cdr_sched = -1; } else { ast_cli_register(&cli_submit); ast_register_atexit(ast_cdr_engine_term); Index: main/rtp.c =================================================================== --- main/rtp.c (revision 98969) +++ main/rtp.c (working copy) @@ -2036,10 +2036,9 @@ void ast_rtp_stop(struct ast_rtp *rtp) { - if (rtp->rtcp && rtp->rtcp->schedid > 0) { - ast_sched_del(rtp->sched, rtp->rtcp->schedid); - rtp->rtcp->schedid = -1; - } + while (rtp->rtcp && rtp->rtcp->schedid > 0 && ast_sched_del(rtp->sched, rtp->rtcp->schedid)) + usleep(1); + rtp->rtcp->schedid = -1; memset(&rtp->them.sin_addr, 0, sizeof(rtp->them.sin_addr)); memset(&rtp->them.sin_port, 0, sizeof(rtp->them.sin_port)); @@ -2143,8 +2142,8 @@ if (rtp->s > -1) close(rtp->s); if (rtp->rtcp) { - if (rtp->rtcp->schedid > 0) - ast_sched_del(rtp->sched, rtp->rtcp->schedid); + while (rtp->rtcp->schedid > 0 && ast_sched_del(rtp->sched, rtp->rtcp->schedid)) + usleep(1); close(rtp->rtcp->s); free(rtp->rtcp); rtp->rtcp=NULL; @@ -2370,8 +2369,8 @@ if (!rtp->rtcp->them.sin_addr.s_addr) { /* This'll stop rtcp for this rtp session */ ast_verbose("RTCP SR transmission error, rtcp halted\n"); - if (rtp->rtcp->schedid > 0) - ast_sched_del(rtp->sched, rtp->rtcp->schedid); + while (rtp->rtcp->schedid > 0 && ast_sched_del(rtp->sched, rtp->rtcp->schedid)) + usleep(1); rtp->rtcp->schedid = -1; return 0; } @@ -2429,8 +2428,8 @@ res = sendto(rtp->rtcp->s, (unsigned int *)rtcpheader, len, 0, (struct sockaddr *)&rtp->rtcp->them, sizeof(rtp->rtcp->them)); if (res < 0) { ast_log(LOG_ERROR, "RTCP SR transmission error to %s:%d, rtcp halted %s\n",ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port), strerror(errno)); - if (rtp->rtcp->schedid > 0) - ast_sched_del(rtp->sched, rtp->rtcp->schedid); + while (rtp->rtcp->schedid > 0 && ast_sched_del(rtp->sched, rtp->rtcp->schedid)) + usleep(1); rtp->rtcp->schedid = -1; return 0; } @@ -2481,8 +2480,8 @@ if (!rtp->rtcp->them.sin_addr.s_addr) { ast_log(LOG_ERROR, "RTCP RR transmission error, rtcp halted\n"); - if (rtp->rtcp->schedid > 0) - ast_sched_del(rtp->sched, rtp->rtcp->schedid); + while (rtp->rtcp->schedid > 0 && ast_sched_del(rtp->sched, rtp->rtcp->schedid)) + usleep(1); rtp->rtcp->schedid = -1; return 0; } @@ -2530,8 +2529,8 @@ if (res < 0) { ast_log(LOG_ERROR, "RTCP RR transmission error, rtcp halted: %s\n",strerror(errno)); /* Remove the scheduler */ - if (rtp->rtcp->schedid > 0) - ast_sched_del(rtp->sched, rtp->rtcp->schedid); + while (rtp->rtcp->schedid > 0 && ast_sched_del(rtp->sched, rtp->rtcp->schedid)) + usleep(1); rtp->rtcp->schedid = -1; return 0; } Index: main/dnsmgr.c =================================================================== --- main/dnsmgr.c (revision 98969) +++ main/dnsmgr.c (working copy) @@ -252,7 +252,8 @@ void dnsmgr_start_refresh(void) { if (refresh_sched > -1) { - ast_sched_del(sched, refresh_sched); + while (refresh_sched > -1 && ast_sched_del(sched, refresh_sched)) + usleep(1); refresh_sched = ast_sched_add_variable(sched, 100, refresh_list, &master_refresh_info, 1); } } @@ -367,8 +368,9 @@ was_enabled = enabled; enabled = 0; - if (refresh_sched > -1) - ast_sched_del(sched, refresh_sched); + while (refresh_sched > -1 && ast_sched_del(sched, refresh_sched)) + usleep(1); + refresh_sched = -1; if ((config = ast_config_load("dnsmgr.conf"))) { if ((enabled_value = ast_variable_retrieve(config, "general", "enable"))) { Index: main/file.c =================================================================== --- main/file.c (revision 98969) +++ main/file.c (working copy) @@ -767,16 +767,16 @@ if (f->owner) { if (f->fmt->format < AST_FORMAT_MAX_AUDIO) { f->owner->stream = NULL; - if (f->owner->streamid > -1) - ast_sched_del(f->owner->sched, f->owner->streamid); + while (f->owner->streamid > -1 && ast_sched_del(f->owner->sched, f->owner->streamid)) + usleep(1); f->owner->streamid = -1; #ifdef HAVE_ZAPTEL ast_settimeout(f->owner, 0, NULL, NULL); #endif } else { f->owner->vstream = NULL; - if (f->owner->vstreamid > -1) - ast_sched_del(f->owner->sched, f->owner->vstreamid); + while (f->owner->vstreamid > -1 && ast_sched_del(f->owner->sched, f->owner->vstreamid)) + usleep(1); f->owner->vstreamid = -1; } }