--- channels/chan_zap.c.orig 2008-03-11 07:27:08.000000000 +1100 +++ channels/chan_zap.c 2008-05-31 16:50:51.000000000 +1000 @@ -333,6 +333,7 @@ int resetpos; time_t lastreset; /*!< time when unused channels were last reset */ long resetinterval; /*!< Interval (in seconds) for resetting unused channels */ + long resettimeout; /*!< Interval (in seconds) for resetting unused channels */ struct zt_pvt *pvts[MAX_CHANNELS]; /*!< Member channel pvt structs */ struct zt_pvt *crvs; /*!< Member CRV structs */ struct zt_pvt *crvend; /*!< Pointer to end of CRV structs */ @@ -485,7 +486,7 @@ unsigned int isidlecall:1; unsigned int proceeding:1; unsigned int progress:1; - unsigned int resetting:1; + time_t resetting; unsigned int setup_ack:1; #endif unsigned int use_smdi:1; /* Whether to use SMDI on this channel */ @@ -620,7 +621,8 @@ .privateprefix = "", .unknownprefix = "", - .resetinterval = 3600 + .resetinterval = 3600, + .resettimeout = 3 }, #endif .chan = { @@ -7349,6 +7351,7 @@ ast_copy_string(pris[span].privateprefix, conf.pri.privateprefix, sizeof(pris[span].privateprefix)); ast_copy_string(pris[span].unknownprefix, conf.pri.unknownprefix, sizeof(pris[span].unknownprefix)); pris[span].resetinterval = conf.pri.resetinterval; + pris[span].resettimeout = conf.pri.resettimeout; tmp->pri = &pris[span]; tmp->prioffset = offset; @@ -8262,6 +8265,7 @@ static int pri_check_restart(struct zt_pri *pri) { + time_t t = time(NULL); do { pri->resetpos++; } while ((pri->resetpos < pri->numchans) && @@ -8270,7 +8274,7 @@ pri->pvts[pri->resetpos]->resetting)); if (pri->resetpos < pri->numchans) { /* Mark the channel as resetting and restart it */ - pri->pvts[pri->resetpos]->resetting = 1; + pri->pvts[pri->resetpos]->resetting = t; pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[pri->resetpos])); } else { pri->resetting = 0; @@ -8416,6 +8420,15 @@ ast_mutex_lock(&pri->lock); if (pri->switchtype != PRI_SWITCH_GR303_TMC && (pri->resetinterval > 0)) { if (pri->resetting && pri_is_up(pri)) { + if (pri->resetpos >= 0 && + pri->pvts[pri->resetpos] && + pri->pvts[pri->resetpos]->resetting > 1000 && + pri->pvts[pri->resetpos]->resetting + pri->resettimeout < t) { + ast_verbose(VERBOSE_PREFIX_3 "Span %d - Recover from deadlock on reset of B-channel %d\n", pri->span, pri->resetpos + 1); + pri->pvts[pri->resetpos]->resetting = 0; + pri_check_restart(pri); + } + if (pri->resetpos < 0) pri_check_restart(pri); } else { @@ -11068,6 +11081,14 @@ else ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d\n", v->value, v->lineno); + } else if (!strcasecmp(v->name, "resettimeout")) { + if (!strcasecmp(v->value, "never")) + confp->pri.resettimeout = -1; + else if (atoi(v->value) != 0) + confp->pri.resettimeout = atoi(v->value); + else + ast_log(LOG_WARNING, "'%s' is not a valid reset timeout, should be >= 1 seconds or 'never' at line %d\n", + v->value, v->lineno); } else if (!strcasecmp(v->name, "minunused")) { confp->pri.minunused = atoi(v->value); } else if (!strcasecmp(v->name, "minidle")) {