@ -2395,8 +2395,18 @@ static struct call_queue *find_queue_by_name_rt(const char *queuename, struct as
return q ;
}
/*! \note Returns a reference to the loaded realtime queue. */
static struct call_queue * load_realtime_queue ( const char * queuename )
/*!
* note */
/*!
* \ internal
* \ brief Returns reference to the named queue . If the queue is realtime , it will load the queue as well .
* \ param queuename - name of the desired queue
*
* \ retval the queue
* \ retval NULL if it doesn ' t exist
*/
static struct call_queue * find_load_queue_rt_friendly ( const char * queuename )
{
struct ast_variable * queue_vars ;
struct ast_config * member_config = NULL ;
@ -2520,7 +2530,7 @@ static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *
int pos = 0 ;
int inserted = 0 ;
if ( ! ( q = load_realtime_ queue( queuename ) ) ) {
if ( ! ( q = find_ load_queue_rt_friendly ( queuename ) ) ) {
return res ;
}
ao2_lock ( q ) ;
@ -5345,7 +5355,7 @@ static int add_to_queue(const char *queuename, const char *interface, const char
/*! \note Ensure the appropriate realtime queue is loaded. Note that this
* short - circuits if the queue is already in memory . */
if ( ! ( q = load_realtime_ queue( queuename ) ) ) {
if ( ! ( q = find_ load_queue_rt_friendly ( queuename ) ) ) {
return res ;
}
@ -5467,45 +5477,95 @@ static int set_member_paused(const char *queuename, const char *interface, const
return found ? RESULT_SUCCESS : RESULT_FAILURE ;
}
/* \brief Sets members penalty, if queuename=NULL we set member penalty in all the queues. */
/*!
* \ internal
* \ brief helper function for set_member_penalty - given a queue , sets all member penalties with the interface
* \ param [ in ] q queue which is having its member ' s penalty changed - must be unlocked prior to calling
* \ param [ in ] interface String of interface used to search for queue members being changed
* \ param [ in ] penalty Value penalty is being changed to for the member .
* \ retval 0 if the there is no member with interface belonging to q and no change is made
* \ retval 1 if the there is a member with interface belonging to q and changes are made
*/
static int set_member_penalty_help_members ( struct call_queue * q , const char * interface , int penalty )
{
struct member * mem ;
int foundinterface = 0 ;
char rtpenalty [ 80 ] ;
ao2_lock ( q ) ;
if ( ( mem = interface_exists ( q , interface ) ) ) {
foundinterface + + ;
if ( ! mem - > realtime ) {
mem - > penalty = penalty ;
} else {
sprintf ( rtpenalty , " %i " , penalty ) ;
update_realtime_member_field ( mem , q - > name , " penalty " , rtpenalty ) ;
}
ast_queue_log ( q - > name , " NONE " , interface , " PENALTY " , " %d " , penalty ) ;
manager_event ( EVENT_FLAG_AGENT , " QueueMemberPenalty " ,
" Queue: %s \r \n "
" Location: %s \r \n "
" Penalty: %d \r \n " ,
q - > name , mem - > interface , penalty ) ;
ao2_ref ( mem , - 1 ) ;
}
ao2_unlock ( q ) ;
return foundinterface ;
}
/*!
* \ internal
* \ brief Sets members penalty , if queuename = NULL we set member penalty in all the queues .
* \ param [ in ] queuename If specified , only act on a member if it belongs to this queue
* \ param [ in ] interface Interface of queue member ( s ) having priority set .
* \ param [ in ] penalty Value penalty is being changed to for each member
*/
static int set_member_penalty ( const char * queuename , const char * interface , int penalty )
{
int foundinterface = 0 , foundqueue = 0 ;
struct call_queue * q ;
struct member * mem ;
char rtpenalty [ 80 ] ;
struct ast_config * queue_config = NULL ;
struct ao2_iterator queue_iter ;
if ( penalty < 0 & & ! negative_penalty_invalid ) {
ast_log ( LOG_ERROR , " Invalid penalty (%d) \n " , penalty ) ;
return RESULT_FAILURE ;
}
if ( ( q = load_realtime_queue ( queuename ) ) ) {
foundqueue + + ;
ao2_lock ( q ) ;
if ( ( mem = interface_exists ( q , interface ) ) ) {
foundinterface + + ;
if ( ! mem - > realtime ) {
mem - > penalty = penalty ;
} else {
sprintf ( rtpenalty , " %i " , penalty ) ;
update_realtime_member_field ( mem , q - > name , " penalty " , rtpenalty ) ;
if ( ast_strlen_zero ( queuename ) ) { /* This means we need to iterate through all the queues. */
if ( ast_check_realtime ( " queues " ) ) {
char * queuename ;
queue_config = ast_load_realtime_multientry ( " queues " , " name LIKE " , " % " , SENTINEL ) ;
if ( queue_config ) {
for ( queuename = ast_category_browse ( queue_config , NULL ) ; ! ast_strlen_zero ( queuename ) ; queuename = ast_category_browse ( queue_config , queuename ) ) {
if ( ( q = find_load_queue_rt_friendly ( queuename ) ) ) {
foundqueue + + ;
foundinterface + = set_member_penalty_help_members ( q , interface , penalty ) ;
}
}
}
ast_queue_log ( q - > name , " NONE " , interface , " PENALTY " , " %d " , penalty ) ;
manager_event ( EVENT_FLAG_AGENT , " QueueMemberPenalty " ,
" Queue: %s \r \n "
" Location: %s \r \n "
" Penalty: %d \r \n " ,
q - > name , mem - > interface , penalty ) ;
ao2_ref ( mem , - 1 ) ;
}
ao2_unlock ( q ) ;
/* After hitting realtime queues, go back and get the regular ones. */
queue_iter = ao2_iterator_init ( queues , 0 ) ;
while ( ( q = ao2_t_iterator_next ( & queue_iter , " Iterate through queues " ) ) ) {
foundqueue + + ;
foundinterface + = set_member_penalty_help_members ( q , interface , penalty ) ;
}
} else { /* We actually have a queuename, so we can just act on the single queue. */
if ( ( q = find_load_queue_rt_friendly ( queuename ) ) ) {
foundqueue + + ;
foundinterface + = set_member_penalty_help_members ( q , interface , penalty ) ;
}
}
if ( foundinterface ) {
return RESULT_SUCCESS ;
} else if ( ! foundqueue ) {
ast_log ( LOG_ERROR , " Invalid queuename \n " ) ;
ast_log ( LOG_ERROR , " Invalid queuename \n " ) ;
} else {
ast_log ( LOG_ERROR , " Invalid interface \n " ) ;
}
@ -5580,7 +5640,7 @@ static void reload_queue_members(void)
}
if ( ! cur_queue ) {
cur_queue = load_realtime_ queue( queue_name ) ;
cur_queue = find_ load_queue_rt_friendly ( queue_name ) ;
}
if ( ! cur_queue ) {
@ -6281,7 +6341,7 @@ static int queue_function_exists(struct ast_channel *chan, const char *cmd, char
ast_log ( LOG_ERROR , " %s requires an argument: queuename \n " , cmd ) ;
return - 1 ;
}
q = load_realtime_ queue( data ) ;
q = find_ load_queue_rt_friendly ( data ) ;
snprintf ( buf , len , " %d " , q ! = NULL ? 1 : 0 ) ;
if ( q ) {
queue_t_unref ( q , " Done with temporary reference in QUEUE_EXISTS() " ) ;
@ -6318,7 +6378,7 @@ static int queue_function_mem_read(struct ast_channel *chan, const char *cmd, ch
AST_STANDARD_APP_ARGS ( args , data ) ;
if ( ( q = load_realtime_ queue( args . queuename ) ) ) {
if ( ( q = find_ load_queue_rt_friendly ( args . queuename ) ) ) {
ao2_lock ( q ) ;
if ( ! strcasecmp ( args . option , " logged " ) ) {
mem_iter = ao2_iterator_init ( q - > members , 0 ) ;
@ -6418,7 +6478,7 @@ static int queue_function_mem_write(struct ast_channel *chan, const char *cmd, c
ast_log ( LOG_ERROR , " Invalid interface, queue or penalty \n " ) ;
return - 1 ;
}
} else if ( ( q = load_realtime_ queue( args . queuename ) ) ) {
} else if ( ( q = find_ load_queue_rt_friendly ( args . queuename ) ) ) {
ao2_lock ( q ) ;
if ( ( m = interface_exists ( q , args . interface ) ) ) {
sprintf ( rtvalue , " %s " , ( memvalue < = 0 ) ? " 0 " : " 1 " ) ;
@ -6480,7 +6540,7 @@ static int queue_function_qac_dep(struct ast_channel *chan, const char *cmd, cha
return - 1 ;
}
if ( ( q = load_realtime_ queue( data ) ) ) {
if ( ( q = find_ load_queue_rt_friendly ( data ) ) ) {
ao2_lock ( q ) ;
mem_iter = ao2_iterator_init ( q - > members , 0 ) ;
while ( ( m = ao2_iterator_next ( & mem_iter ) ) ) {
@ -7151,7 +7211,7 @@ static char *__queues_show(struct mansession *s, int fd, int argc, const char *
}
if ( argc = = 3 ) { /* specific queue */
if ( ( q = load_realtime_ queue( argv [ 2 ] ) ) ) {
if ( ( q = find_ load_queue_rt_friendly ( argv [ 2 ] ) ) ) {
queue_t_unref ( q , " Done with temporary pointer " ) ;
}
} else if ( ast_check_realtime ( " queues " ) ) {
@ -7162,7 +7222,7 @@ static char *__queues_show(struct mansession *s, int fd, int argc, const char *
char * queuename ;
if ( cfg ) {
for ( queuename = ast_category_browse ( cfg , NULL ) ; ! ast_strlen_zero ( queuename ) ; queuename = ast_category_browse ( cfg , queuename ) ) {
if ( ( q = load_realtime_ queue( queuename ) ) ) {
if ( ( q = find_ load_queue_rt_friendly ( queuename ) ) ) {
queue_t_unref ( q , " Done with temporary pointer " ) ;
}
}
@ -7182,7 +7242,7 @@ static char *__queues_show(struct mansession *s, int fd, int argc, const char *
* been deleted from the in - core container
*/
if ( q - > realtime ) {
realtime_queue = load_realtime_ queue( q - > name ) ;
realtime_queue = find_ load_queue_rt_friendly ( q - > name ) ;
if ( ! realtime_queue ) {
ao2_unlock ( q ) ;
queue_t_unref ( q , " Done with iterator " ) ;
@ -8512,7 +8572,7 @@ static int queues_data_provider_get(const struct ast_data_search *search,
for ( queuename = ast_category_browse ( cfg , NULL ) ;
! ast_strlen_zero ( queuename ) ;
queuename = ast_category_browse ( cfg , queuename ) ) {
if ( ( queue = load_realtime_ queue( queuename ) ) ) {
if ( ( queue = find_ load_queue_rt_friendly ( queuename ) ) ) {
queue_unref ( queue ) ;
}
}
@ -8524,7 +8584,7 @@ static int queues_data_provider_get(const struct ast_data_search *search,
while ( ( queue = ao2_iterator_next ( & i ) ) ) {
ao2_lock ( queue ) ;
if ( queue - > realtime ) {
queue_realtime = load_realtime_ queue( queue - > name ) ;
queue_realtime = find_ load_queue_rt_friendly ( queue - > name ) ;
if ( ! queue_realtime ) {
ao2_unlock ( queue ) ;
queue_unref ( queue ) ;
@ -8688,7 +8748,7 @@ static struct member *find_member_by_queuename_and_interface(const char *queuena
struct member * mem = NULL ;
struct call_queue * q ;
if ( ( q = load_realtime_ queue( queuename ) ) ) {
if ( ( q = find_ load_queue_rt_friendly ( queuename ) ) ) {
ao2_lock ( q ) ;
mem = ao2_find ( q - > members , interface , OBJ_KEY ) ;
ao2_unlock ( q ) ;