[Asterisk-Dev] PauseQueueMember

Corey Frang corey at rockriver.net
Mon Oct 17 14:53:14 MST 2005


So, PauseQueueMember works great.

Only one problem, The Dial Plan logic offers >NO< way to guarntee to 
call UnPauseQueueMember when the channel hangs up.

If the >called< party hangs up, a "g" to the Dial() app will work.. If 
the >calling< party hangs up, the dialplan has no way to continue.

------

So, I started digging and came up with this patch for the problem.

My Question, I know I should probably be locking some mutex somewhere, 
or that this might not be the best way to do this functionality, and I'm 
looking for feedback on it.

I opened up a bug on this issue, and submited my patch (also which i'm 
mailing) and would like feedback on it.

http://bugs.digium.com/view.php?id=5452

-- 
Rock River Internet                                Corey Frang
202 W. State St, 8th Floor                 corey at rockriver.net
Rockford, IL 61101                      815-968-9888 Ext. 2205
USA                                               fax 968-6888

-------------- next part --------------
Index: app_queue.c
===================================================================
RCS file: /usr/cvsroot/asterisk/apps/app_queue.c,v
retrieving revision 1.166
diff -r1.166 app_queue.c
174c174
< "   PauseQueueMember([queuename]|interface):\n"
---
> "   PauseQueueMember([queuename]|interface[|options]):\n"
183a184,186
> " Options: \n"
> "   h - When the channel that called this hangs up, UnPause this \n"
> "       queue member\n"
424a428,444
> 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;
> 
> }
> 
497a518,538
> 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;
> }
> 
2406c2447
< 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)
2426a2468,2469
> 				check_for_hangups(mem, pausechan);
> 
2542c2585,2586
< 	char *queuename, *interface;
---
> 	char *queuename, *interface, *options;
> 	struct ast_channel *pausechan = NULL;
2561,2562d2604
< 	LOCAL_USER_ADD(u);
< 
2566c2608,2617
< 	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)) {
2607c2658
< 	if (set_member_paused(queuename, interface, 0)) {
---
> 	if (set_member_paused(queuename, interface, 0, NULL)) {
3482c3533
< 	if (set_member_paused(queuename, interface, paused))
---
> 	if (set_member_paused(queuename, interface, paused, NULL))


More information about the asterisk-dev mailing list