fix penalty behavior, thanks florian!! (bug #3114)

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/v1-0@4883 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Russell Bryant
2005-01-23 23:57:41 +00:00
parent 36d08dc8f0
commit d9d599a84d
2 changed files with 50 additions and 27 deletions

View File

@@ -3,6 +3,11 @@
is available through the Asterisk-CVS mailing list hosted is available through the Asterisk-CVS mailing list hosted
at http://lists.digium.com. at http://lists.digium.com.
Asterisk 1.0.5
-- chan_zap
-- fix a callerid bug introduced in 1.0.4
-- app_queue
-- fix some penalty behavior
Asterisk 1.0.4 Asterisk 1.0.4
-- general -- general
-- fix memory leak evident with extensive use of variables -- fix memory leak evident with extensive use of variables

View File

@@ -545,7 +545,7 @@ static void hanguptree(struct localuser *outgoing, struct ast_channel *exception
} }
} }
static int ring_entry(struct queue_ent *qe, struct localuser *tmp) static int ring_entry(struct queue_ent *qe, struct localuser *tmp, int *busies)
{ {
int res; int res;
if (qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime)) { if (qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime)) {
@@ -553,6 +553,7 @@ static int ring_entry(struct queue_ent *qe, struct localuser *tmp)
if (qe->chan->cdr) if (qe->chan->cdr)
ast_cdr_busy(qe->chan->cdr); ast_cdr_busy(qe->chan->cdr);
tmp->stillgoing = 0; tmp->stillgoing = 0;
(*busies)++;
return 0; return 0;
} }
/* Request the peer */ /* Request the peer */
@@ -564,6 +565,7 @@ static int ring_entry(struct queue_ent *qe, struct localuser *tmp)
if (qe->chan->cdr) if (qe->chan->cdr)
ast_cdr_busy(qe->chan->cdr); ast_cdr_busy(qe->chan->cdr);
tmp->stillgoing = 0; tmp->stillgoing = 0;
(*busies)++;
return 0; return 0;
} }
tmp->chan->appl = "AppQueue"; tmp->chan->appl = "AppQueue";
@@ -594,6 +596,7 @@ static int ring_entry(struct queue_ent *qe, struct localuser *tmp)
ast_hangup(tmp->chan); ast_hangup(tmp->chan);
tmp->chan = NULL; tmp->chan = NULL;
tmp->stillgoing = 0; tmp->stillgoing = 0;
(*busies)++;
return 0; return 0;
} else { } else {
if (qe->parent->eventwhencalled) { if (qe->parent->eventwhencalled) {
@@ -611,10 +614,10 @@ static int ring_entry(struct queue_ent *qe, struct localuser *tmp)
if (option_verbose > 2) if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Called %s/%s\n", tmp->tech, tmp->numsubst); ast_verbose(VERBOSE_PREFIX_3 "Called %s/%s\n", tmp->tech, tmp->numsubst);
} }
return 0; return 1;
} }
static int ring_one(struct queue_ent *qe, struct localuser *outgoing) static int ring_one(struct queue_ent *qe, struct localuser *outgoing, int *busies)
{ {
struct localuser *cur; struct localuser *cur;
struct localuser *best; struct localuser *best;
@@ -636,9 +639,9 @@ static int ring_one(struct queue_ent *qe, struct localuser *outgoing)
/* Ring everyone who shares this best metric (for ringall) */ /* Ring everyone who shares this best metric (for ringall) */
cur = outgoing; cur = outgoing;
while(cur) { while(cur) {
if (cur->stillgoing && !cur->chan && (cur->metric == bestmetric)) { if (cur->stillgoing && !cur->chan && (cur->metric <= bestmetric)) {
ast_log(LOG_DEBUG, "(Parallel) Trying '%s/%s' with metric %d\n", cur->tech, cur->numsubst, cur->metric); ast_log(LOG_DEBUG, "(Parallel) Trying '%s/%s' with metric %d\n", cur->tech, cur->numsubst, cur->metric);
ring_entry(qe, cur); ring_entry(qe, cur, busies);
} }
cur = cur->next; cur = cur->next;
} }
@@ -647,7 +650,7 @@ static int ring_one(struct queue_ent *qe, struct localuser *outgoing)
if (option_debug) if (option_debug)
ast_log(LOG_DEBUG, "Trying '%s/%s' with metric %d\n", ast_log(LOG_DEBUG, "Trying '%s/%s' with metric %d\n",
best->tech, best->numsubst, best->metric); best->tech, best->numsubst, best->metric);
ring_entry(qe, best); ring_entry(qe, best, busies);
} }
} }
} while (best && !best->chan); } while (best && !best->chan);
@@ -711,15 +714,36 @@ static int valid_exit(struct queue_ent *qe, char digit)
#define AST_MAX_WATCHERS 256 #define AST_MAX_WATCHERS 256
static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser *outgoing, int *to, int *allowredir_in, int *allowredir_out, int *allowdisconnect_in, int *allowdisconnect_out, char *digit) #define BUILD_STATS do { \
o = outgoing; \
found = -1; \
pos = 1; \
numlines = 0; \
watchers[0] = in; \
while(o) { \
/* Keep track of important channels */ \
if (o->stillgoing) { \
stillgoing = 1; \
if (o->chan) { \
watchers[pos++] = o->chan; \
found = 1; \
} \
} \
o = o->next; \
numlines++; \
} \
} while(0)
static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser *outgoing, int *to, int *allowredir_in, int *allowredir_out, int *allowdisconnect_in, int *allowdisconnect_out, char *digit, int prebusies)
{ {
char *queue = qe->parent->name; char *queue = qe->parent->name;
struct localuser *o; struct localuser *o;
int found; int found;
int numlines; int numlines;
int sentringing = 0; int sentringing = 0;
int numbusies = 0; int numbusies = prebusies;
int orig = *to; int orig = *to;
int stillgoing = 0;
struct ast_frame *f; struct ast_frame *f;
struct localuser *peer = NULL; struct localuser *peer = NULL;
struct ast_channel *watchers[AST_MAX_WATCHERS]; struct ast_channel *watchers[AST_MAX_WATCHERS];
@@ -728,25 +752,18 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
struct ast_channel *in = qe->chan; struct ast_channel *in = qe->chan;
while(*to && !peer) { while(*to && !peer) {
o = outgoing; BUILD_STATS;
found = -1; if ((found < 0) && stillgoing && !qe->parent->strategy) {
pos = 1; /* On "ringall" strategy we only move to the next penalty level
numlines = 0; when *all* ringing phones are done in the current penalty level */
watchers[0] = in; ring_one(qe, outgoing, &numbusies);
while(o) { BUILD_STATS;
/* Keep track of important channels */
if (o->stillgoing && o->chan) {
watchers[pos++] = o->chan;
found = 1;
}
o = o->next;
numlines++;
} }
if (found < 0) { if (found < 0) {
if (numlines == numbusies) { if (numlines == numbusies) {
ast_log(LOG_DEBUG, "Everyone is busy at this time\n"); ast_log(LOG_DEBUG, "Everyone is busy at this time\n");
} else { } else {
ast_log(LOG_NOTICE, "No one is answering queue '%s'\n", queue); ast_log(LOG_NOTICE, "No one is answering queue '%s' (%d/%d)\n", queue, numlines, numbusies);
} }
*to = 0; *to = 0;
return NULL; return NULL;
@@ -790,7 +807,7 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
ast_hangup(o->chan); ast_hangup(o->chan);
o->chan = NULL; o->chan = NULL;
if (qe->parent->strategy) if (qe->parent->strategy)
ring_one(qe, outgoing); ring_one(qe, outgoing, &numbusies);
numbusies++; numbusies++;
break; break;
case AST_CONTROL_CONGESTION: case AST_CONTROL_CONGESTION:
@@ -802,7 +819,7 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
ast_hangup(o->chan); ast_hangup(o->chan);
o->chan = NULL; o->chan = NULL;
if (qe->parent->strategy) if (qe->parent->strategy)
ring_one(qe, outgoing); ring_one(qe, outgoing, &numbusies);
numbusies++; numbusies++;
break; break;
case AST_CONTROL_RINGING: case AST_CONTROL_RINGING:
@@ -828,7 +845,7 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
ast_hangup(o->chan); ast_hangup(o->chan);
o->chan = NULL; o->chan = NULL;
if (qe->parent->strategy) if (qe->parent->strategy)
ring_one(qe, outgoing); ring_one(qe, outgoing, &numbusies);
} }
} }
o = o->next; o = o->next;
@@ -1024,6 +1041,7 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri
struct member *member; struct member *member;
int res = 0, bridge = 0; int res = 0, bridge = 0;
int zapx = 2; int zapx = 2;
int numbusies = 0;
int x=0; int x=0;
char *announce = NULL; char *announce = NULL;
char digit = 0; char digit = 0;
@@ -1106,9 +1124,9 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri
to = qe->parent->timeout * 1000; to = qe->parent->timeout * 1000;
else else
to = -1; to = -1;
ring_one(qe, outgoing); ring_one(qe, outgoing, &numbusies);
ast_mutex_unlock(&qe->parent->lock); ast_mutex_unlock(&qe->parent->lock);
lpeer = wait_for_answer(qe, outgoing, &to, &allowredir_in, &allowredir_out, &allowdisconnect_in, &allowdisconnect_out, &digit); lpeer = wait_for_answer(qe, outgoing, &to, &allowredir_in, &allowredir_out, &allowdisconnect_in, &allowdisconnect_out, &digit, numbusies);
ast_mutex_lock(&qe->parent->lock); ast_mutex_lock(&qe->parent->lock);
if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY) { if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY) {
store_next(qe, outgoing); store_next(qe, outgoing);