diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 53c80e9472253210a1c92de2ab11cf16b1ee131b..f8b0470670ab85e0c056061d5ba27f4893f8079d 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -2373,9 +2373,8 @@ static enum sip_result __sip_reliable_xmit(struct sip_pvt *p, int seqno, int res siptimer_a = pkt->timer_t1 * 2; /* Schedule retransmission */ - if (pkt->retransid > -1) - ast_sched_del(sched, pkt->retransid); - pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); + pkt->retransid = ast_sched_replace_variable(pkt->retransid, sched, + siptimer_a, retrans_pkt, pkt, 1); if (sipdebug) ast_debug(4, "*** SIP TIMER: Initalizing retransmit timer on packet: Id #%d\n", pkt->retransid); if (sipmethod == SIP_INVITE) { @@ -3134,10 +3133,8 @@ static struct sip_peer *realtime_peer(const char *newpeername, struct sockaddr_i /* 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); - } - peer->expire = ast_sched_add(sched, global_rtautoclear * 1000, expire_register, (void *)peer); + peer->expire = ast_sched_replace(peer->expire, sched, + global_rtautoclear * 1000, expire_register, (void *) peer); } ASTOBJ_CONTAINER_LINK(&peerl,peer); } else { @@ -3563,9 +3560,8 @@ static int sip_call(struct ast_channel *ast, char *dest, int timeout) p->invitestate = INV_CALLING; /* Initialize auto-congest time */ - if (p->initid > -1) - ast_sched_del(sched, p->initid); - p->initid = ast_sched_add(sched, SIP_TRANS_TIMEOUT, auto_congest, dialog_ref(p)); + p->initid = ast_sched_replace(p->initid, sched, SIP_TRANS_TIMEOUT, + auto_congest, dialog_ref(p)); } return res; @@ -8182,8 +8178,8 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char * * 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); + r->timeout = ast_sched_replace(r->timeout, sched, + global_reg_timeout * 1000, sip_reg_timeout, r); 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); @@ -8232,11 +8228,9 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char * /* 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); - } - r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); + r->timeout = ast_sched_replace(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r); ast_debug(1, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); } @@ -8613,14 +8607,12 @@ static void reg_source_db(struct sip_peer *peer) 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); - peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, peer); + peer->pokeexpire = ast_sched_replace(peer->pokeexpire, sched, + ast_random() % 5000 + 1, sip_poke_peer_s, peer); } else sip_poke_peer(peer); - if (peer->expire > -1) - ast_sched_del(sched, peer->expire); - peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer); + peer->expire = ast_sched_replace(peer->expire, sched, + (expiry + 10) * 1000, expire_register, peer); register_peer_exten(peer, TRUE); } @@ -13443,9 +13435,7 @@ static int handle_response_register(struct sip_pvt *p, int resp, char *rest, str r->refresh= (int) expires_ms / 1000; /* Schedule re-registration before we expire */ - if (r->expire > -1) - ast_sched_del(sched, r->expire); - r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); + r->expire = ast_sched_replace(r->expire, sched, expires_ms, sip_reregister, r); registry_unref(r); } return 1; @@ -13490,12 +13480,10 @@ static void handle_response_peerpoke(struct sip_pvt *p, int resp, struct sip_req register_peer_exten(peer, TRUE); } - if (peer->pokeexpire > -1) - ast_sched_del(sched, peer->pokeexpire); p->needdestroy = 1; /* Try again eventually */ - peer->pokeexpire = ast_sched_add(sched, + peer->pokeexpire = ast_sched_replace(peer->pokeexpire, sched, is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); } @@ -16570,9 +16558,8 @@ static int sip_poke_noanswer(void *data) peer->lastms = -1; ast_device_state_changed("SIP/%s", peer->name); /* Try again quickly */ - if (peer->pokeexpire > -1) - ast_sched_del(sched, peer->pokeexpire); - peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); + peer->pokeexpire = ast_sched_replace(peer->pokeexpire, sched, + DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); return 0; } @@ -16635,9 +16622,8 @@ static int sip_poke_peer(struct sip_peer *peer) if (xmitres == XMIT_ERROR) sip_poke_noanswer(peer); /* Immediately unreachable, network problems */ else { - if (peer->pokeexpire > -1) - ast_sched_del(sched, peer->pokeexpire); - peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, sip_poke_noanswer, peer); + peer->pokeexpire = ast_sched_replace(peer->pokeexpire, sched, + DEFAULT_MAXMS * 2, sip_poke_noanswer, peer); } return 0; @@ -18672,10 +18658,9 @@ static void sip_poke_all_peers(void) ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { ASTOBJ_WRLOCK(iterator); - if (iterator->pokeexpire > -1) - ast_sched_del(sched, iterator->pokeexpire); ms += 100; - iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, iterator); + iterator->pokeexpire = ast_sched_replace(iterator->pokeexpire, + sched, ms, sip_poke_peer_s, iterator); ASTOBJ_UNLOCK(iterator); } while (0) ); @@ -18694,10 +18679,9 @@ static void sip_send_all_registers(void) ms = regspacing; ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { ASTOBJ_WRLOCK(iterator); - if (iterator->expire > -1) - ast_sched_del(sched, iterator->expire); ms += regspacing; - iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); + iterator->expire = ast_sched_replace(iterator->expire, + sched, ms, sip_reregister, iterator); ASTOBJ_UNLOCK(iterator); } while (0) ); diff --git a/include/asterisk/sched.h b/include/asterisk/sched.h index 00dc7a0a200a3b3906b1806a342085ef9e42d606..5238ecab5785ef23650c6d265e7688623b64fe22 100644 --- a/include/asterisk/sched.h +++ b/include/asterisk/sched.h @@ -71,6 +71,18 @@ typedef int (*ast_sched_cb)(void *data); */ int ast_sched_add(struct sched_context *con, int when, ast_sched_cb callback, void *data); +/*! + * \brief replace a scheduler entry + * + * This deletes the scheduler entry for old_id if it exists, and then + * calls ast_sched_add to create a new entry. A negative old_id will + * be ignored. + * + * \retval -1 failure + * \retval otherwise, returns scheduled item ID + */ +int ast_sched_replace(int old_id, struct sched_context *con, int when, ast_sched_cb callback, void *data); + /*!Adds a scheduled event with rescheduling support * \param con Scheduler context to add * \param when how many milliseconds to wait for event to occur @@ -86,6 +98,18 @@ int ast_sched_add(struct sched_context *con, int when, ast_sched_cb callback, vo */ int ast_sched_add_variable(struct sched_context *con, int when, ast_sched_cb callback, void *data, int variable); +/*! + * \brief replace a scheduler entry + * + * This deletes the scheduler entry for old_id if it exists, and then + * calls ast_sched_add to create a new entry. A negative old_id will + * be ignored. + * + * \retval -1 failure + * \retval otherwise, returns scheduled item ID + */ +int ast_sched_replace_variable(int old_id, struct sched_context *con, int when, ast_sched_cb callback, void *data, int variable); + /*! \brief Deletes a scheduled event * Remove this event from being run. A procedure should not remove its * own event, but return 0 instead. diff --git a/main/sched.c b/main/sched.c index 1a07ab65912838b92395bcf8f65227d20bad4671..602c8516e5b1218700ad287777fc19bc382ac807 100644 --- a/main/sched.c +++ b/main/sched.c @@ -207,6 +207,12 @@ static int sched_settime(struct timeval *tv, int when) return 0; } +int ast_sched_replace_variable(int old_id, struct sched_context *con, int when, ast_sched_cb callback, void *data, int variable) +{ + if (old_id > -1) + ast_sched_del(con, old_id); + return ast_sched_add_variable(con, when, callback, data, variable); +} /*! \brief * Schedule callback(data) to happen when ms into the future @@ -244,6 +250,13 @@ int ast_sched_add_variable(struct sched_context *con, int when, ast_sched_cb cal return res; } +int ast_sched_replace(int old_id, struct sched_context *con, int when, ast_sched_cb callback, void *data) +{ + if (old_id > -1) + ast_sched_del(con, old_id); + return ast_sched_add(con, when, callback, data); +} + int ast_sched_add(struct sched_context *con, int when, ast_sched_cb callback, void *data) { return ast_sched_add_variable(con, when, callback, data, 0);