Index: app_queue.c =================================================================== RCS file: /usr/cvsroot/asterisk/apps/app_queue.c,v retrieving revision 1.166 diff -u -r1.166 app_queue.c --- app_queue.c 30 Sep 2005 14:01:56 -0000 1.166 +++ app_queue.c 17 Oct 2005 22:35:11 -0000 @@ -171,7 +171,7 @@ static char *app_pqm = "PauseQueueMember" ; static char *app_pqm_synopsis = "Pauses a queue member" ; static char *app_pqm_descrip = -" PauseQueueMember([queuename]|interface):\n" +" PauseQueueMember([queuename]|interface[|options]):\n" "Pauses (blocks calls for) a queue member.\n" "The given interface will be paused in the given queue. This prevents\n" "any calls from being sent from the queue to the interface until it is\n" @@ -181,6 +181,9 @@ "is given and the interface is not in any queue, it will jump to\n" " priority n+101, if it exists. Returns -1 if the interface is not\n" "found and no extension to jump to exists, 0 otherwise.\n" +" Options: \n" +" h - When the channel that called this hangs up, UnPause this \n" +" queue member\n" "Example: PauseQueueMember(|SIP/3000)\n"; static char *app_upqm = "UnpauseQueueMember" ; @@ -422,6 +425,23 @@ char dev[0]; }; +struct waitpause { + struct ast_channel *pausechan; + struct member *mem; +}; + +static void *queuecheckhangupthread(void *data) { + struct waitpause *wp = data; + + while (wp->pausechan && !ast_check_hangup(wp->pausechan)); + + wp->mem->paused = 0; + + free(wp); + return NULL; + +} + static void *changethread(void *data) { struct ast_call_queue *q; @@ -495,6 +515,27 @@ return 0; } +static int check_for_hangups(struct member *mem, struct ast_channel *pausechan) +{ + struct waitpause *wp; + pthread_t t; + pthread_attr_t attr; + + if (!pausechan || !mem) return 0; + wp = malloc(sizeof(struct waitpause)); + if (wp) { + wp->mem = mem; + wp->pausechan = pausechan; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + if (ast_pthread_create(&t, &attr, queuecheckhangupthread, wp)) { + ast_log(LOG_WARNING, "Failed to create hangup thread!\n"); + free(wp); + } + } + return 0; +} + static struct member *create_queue_member(char *interface, int penalty, int paused) { struct member *cur; @@ -2403,7 +2444,7 @@ return res; } -static int set_member_paused(char *queuename, char *interface, int paused) +static int set_member_paused(char *queuename, char *interface, int paused, struct ast_channel *pausechan) { int found = 0; struct ast_call_queue *q; @@ -2424,6 +2465,8 @@ ast_log(LOG_DEBUG, "%spausing already-%spaused queue member %s:%s\n", (paused ? "" : "un"), (paused ? "" : "un"), q->name, interface); mem->paused = paused; + check_for_hangups(mem, pausechan); + if (queue_persistent_members) dump_queue_members(q); @@ -2539,7 +2582,8 @@ static int pqm_exec(struct ast_channel *chan, void *data) { struct localuser *u; - char *queuename, *interface; + char *queuename, *interface, *options; + struct ast_channel *pausechan = NULL; if (!data) { ast_log(LOG_WARNING, "PauseQueueMember requires an argument ([queuename]|interface])\n"); @@ -2558,12 +2602,19 @@ return -1; } - LOCAL_USER_ADD(u); - *interface = '\0'; interface++; - if (set_member_paused(queuename, interface, 1)) { + options = strchr(interface, '|'); + if (options) + { + *options++ = '\0'; + if (strchr(options, 'h')) pausechan = chan; + } + + LOCAL_USER_ADD(u); + + if (set_member_paused(queuename, interface, 1, pausechan)) { ast_log(LOG_WARNING, "Attempt to pause interface %s, not found\n", interface); if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) { LOCAL_USER_REMOVE(u); @@ -2604,7 +2655,7 @@ *interface = '\0'; interface++; - if (set_member_paused(queuename, interface, 0)) { + if (set_member_paused(queuename, interface, 0, NULL)) { ast_log(LOG_WARNING, "Attempt to unpause interface %s, not found\n", interface); if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) { LOCAL_USER_REMOVE(u); @@ -3479,7 +3530,7 @@ paused = abs(ast_true(paused_s)); - if (set_member_paused(queuename, interface, paused)) + if (set_member_paused(queuename, interface, paused, NULL)) astman_send_error(s, m, "Interface not found"); else if (paused)