Index: apps/app_queue.c =================================================================== --- apps/app_queue.c (revision 65499) +++ apps/app_queue.c (working copy) @@ -257,6 +257,9 @@ /*! \brief queues.conf [general] option */ static int montype_default = 0; +/*! \brief queues.conf [general] option */ +static int shared_lastcall = 0; + enum queue_result { QUEUE_UNKNOWN = 0, QUEUE_TIMEOUT = 1, @@ -294,6 +297,7 @@ int metric; int oldstatus; time_t lastcall; + struct call_queue *lastqueue; struct member *member; }; @@ -328,6 +332,7 @@ int status; /*!< Status of queue member */ int paused; /*!< Are we paused (not accepting calls)? */ time_t lastcall; /*!< When last successful call was hungup */ + struct call_queue *lastqueue; /*!< Last queue we received a call */ unsigned int dead:1; /*!< Used to detect members deleted in realtime */ unsigned int delme:1; /*!< Flag to delete entry on reload */ struct member *next; /*!< Next member */ @@ -1665,9 +1670,10 @@ char *location; /* on entry here, we know that tmp->chan == NULL */ - if (qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime)) { + if ((tmp->lastqueue && tmp->lastqueue->wrapuptime && (time(NULL) - tmp->lastcall < tmp->lastqueue->wrapuptime)) || + (!tmp->lastqueue && qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime))) { if (option_debug) - ast_log(LOG_DEBUG, "Wrapuptime not yet expired for %s\n", tmp->interface); + ast_log(LOG_DEBUG, "Wrapuptime not yet expired on queue %s for %s\n", (tmp->lastqueue? tmp->lastqueue->name : qe->parent->name), tmp->interface); if (qe->chan->cdr) ast_cdr_busy(qe->chan->cdr); tmp->stillgoing = 0; @@ -2315,21 +2321,43 @@ static int update_queue(struct call_queue *q, struct member *member) { struct member *cur; + struct call_queue *qtmp; /* Since a reload could have taken place, we have to traverse the list to be sure it's still valid */ - ast_mutex_lock(&q->lock); - cur = q->members; - while (cur) { - if (member == cur) { - time(&cur->lastcall); - cur->calls++; - break; + if (shared_lastcall) { + AST_LIST_LOCK(&queues); + AST_LIST_TRAVERSE(&queues, qtmp, list) { + ast_mutex_lock(&qtmp->lock); + for (cur = qtmp->members; cur; cur = cur->next) { + if (!strcasecmp(member->interface, cur->interface)) { + time(&cur->lastcall); + cur->calls++; + cur->lastqueue = q; + break; + } + } + ast_mutex_unlock(&qtmp->lock); } - cur = cur->next; + AST_LIST_UNLOCK(&queues); + ast_mutex_lock(&q->lock); + q->callscompleted++; + ast_mutex_unlock(&q->lock); + } else { + ast_mutex_lock(&q->lock); + cur = q->members; + while (cur) { + if (member == cur) { + time(&cur->lastcall); + cur->calls++; + cur->lastqueue = q; + break; + } + cur = cur->next; + } + q->callscompleted++; + ast_mutex_unlock(&q->lock); } - q->callscompleted++; - ast_mutex_unlock(&q->lock); return 0; } @@ -2516,6 +2544,7 @@ tmp->member = cur; /* Never directly dereference! Could change on reload */ tmp->oldstatus = cur->status; tmp->lastcall = cur->lastcall; + tmp->lastqueue = cur->lastqueue; ast_copy_string(tmp->interface, cur->interface, sizeof(tmp->interface)); /* Special case: If we ring everyone, go ahead and ring them, otherwise just calculate their metric for the appropriate strategy */ @@ -4002,6 +4031,9 @@ if ((general_val = ast_variable_retrieve(cfg, "general", "monitor-type"))) if (!strcasecmp(general_val, "mixmonitor")) montype_default = 1; + shared_lastcall = 0; + if ((general_val = ast_variable_retrieve(cfg, "general", "shared_lastcall"))) + shared_lastcall = ast_true(general_val); } else { /* Define queue */ /* Look for an existing one */ AST_LIST_TRAVERSE(&queues, q, list) { Index: configs/queues.conf.sample =================================================================== --- configs/queues.conf.sample (revision 65499) +++ configs/queues.conf.sample (working copy) @@ -51,6 +51,13 @@ ; an application call from extensions.conf: ; Queue(queuename|[options]|[optionalurl]|[announceoverride]|[timeout]) ; example: Queue(dave|t|||45) +shared_lastcall = yes|no +; +; Make the lastcall and calls received be the same in members logged +; in more than one queue. +; This is usefull to make the queue respect the wrapuptime of another +; queue for a shared member. +; ;[markq] ;