mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 18:55:19 +00:00 
			
		
		
		
	Add support for new PING/PONG on zaptel which reduces the # of file descriptors on SIP/IAX channels (when zaptel interface is available) by 2 per channel
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@2467 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		
							
								
								
									
										80
									
								
								channel.c
									
									
									
									
									
								
							
							
						
						
									
										80
									
								
								channel.c
									
									
									
									
									
								
							| @@ -38,6 +38,9 @@ | ||||
| #ifdef ZAPTEL_OPTIMIZATIONS | ||||
| #include <sys/ioctl.h> | ||||
| #include <linux/zaptel.h> | ||||
| #ifndef ZT_TIMERPING | ||||
| #error "You need newer zaptel!  Please cvs update zaptel" | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| /* uncomment if you have problems with 'monitoring' synchronized files */ | ||||
| @@ -284,6 +287,18 @@ struct ast_channel *ast_channel_alloc(int needqueue) | ||||
| 			if (tmp->sched) { | ||||
| 				for (x=0;x<AST_MAX_FDS - 1;x++) | ||||
| 					tmp->fds[x] = -1; | ||||
| #ifdef ZAPTEL_OPTIMIZATIONS | ||||
| 				tmp->timingfd = open("/dev/zap/timer", O_RDWR); | ||||
| 				if (tmp->timingfd > -1) { | ||||
| 					/* Check if timing interface supports new | ||||
| 					   ping/pong scheme */ | ||||
| 					flags = 1; | ||||
| 					if (!ioctl(tmp->timingfd, ZT_TIMERPONG, &flags)) | ||||
| 						needqueue = 0; | ||||
| 				} | ||||
| #else | ||||
| 				tmp->timingfd = -1;					 | ||||
| #endif					 | ||||
| 				if (needqueue &&   | ||||
| 					pipe(pvt->alertpipe)) { | ||||
| 					ast_log(LOG_WARNING, "Alert pipe creation failed!\n"); | ||||
| @@ -292,19 +307,14 @@ struct ast_channel *ast_channel_alloc(int needqueue) | ||||
| 					tmp = NULL; | ||||
| 					pvt = NULL; | ||||
| 				} else { | ||||
| 					/* Make sure we've got it done right if they don't */ | ||||
| 					if (needqueue) { | ||||
| 						flags = fcntl(pvt->alertpipe[0], F_GETFL); | ||||
| 						fcntl(pvt->alertpipe[0], F_SETFL, flags | O_NONBLOCK); | ||||
| 						flags = fcntl(pvt->alertpipe[1], F_GETFL); | ||||
| 						fcntl(pvt->alertpipe[1], F_SETFL, flags | O_NONBLOCK); | ||||
| 					} else | ||||
| 					} else  | ||||
| 					/* Make sure we've got it done right if they don't */ | ||||
| 						pvt->alertpipe[0] = pvt->alertpipe[1] = -1; | ||||
| #ifdef ZAPTEL_OPTIMIZATIONS | ||||
| 					tmp->timingfd = open("/dev/zap/timer", O_RDWR); | ||||
| #else | ||||
| 					tmp->timingfd = -1;					 | ||||
| #endif | ||||
| 					/* Always watch the alertpipe */ | ||||
| 					tmp->fds[AST_MAX_FDS-1] = pvt->alertpipe[0]; | ||||
| 					/* And timing pipe */ | ||||
| @@ -392,6 +402,10 @@ int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin, int lock) | ||||
| 		if (write(chan->pvt->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah)) | ||||
| 			ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n", | ||||
| 				chan->name, f->frametype, f->subclass, qlen, strerror(errno)); | ||||
| #ifdef ZAPTEL_OPTIMIZATIONS | ||||
| 	} else if (chan->timingfd > -1) { | ||||
| 		ioctl(chan->timingfd, ZT_TIMERPING, &blah); | ||||
| #endif				 | ||||
| 	} else if (chan->blocking) { | ||||
| 		pthread_kill(chan->blocker, SIGURG); | ||||
| 	} | ||||
| @@ -1023,6 +1037,7 @@ struct ast_frame *ast_read(struct ast_channel *chan) | ||||
| #ifdef ZAPTEL_OPTIMIZATIONS | ||||
| 	int (*func)(void *); | ||||
| 	void *data; | ||||
| 	int res; | ||||
| #endif | ||||
| 	static struct ast_frame null_frame =  | ||||
| 	{ | ||||
| @@ -1067,24 +1082,45 @@ struct ast_frame *ast_read(struct ast_channel *chan) | ||||
| 	if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && chan->exception) { | ||||
| 		chan->exception = 0; | ||||
| 		blah = -1; | ||||
| 		ioctl(chan->timingfd, ZT_TIMERACK, &blah); | ||||
| 		func = chan->timingfunc; | ||||
| 		data = chan->timingdata; | ||||
| 		ast_mutex_unlock(&chan->lock); | ||||
| 		if (func) { | ||||
| 		/* IF we can't get event, assume it's an expired as-per the old interface */ | ||||
| 		res = ioctl(chan->timingfd, ZT_GETEVENT, &blah); | ||||
| 		if (res)  | ||||
| 			blah = ZT_EVENT_TIMER_EXPIRED; | ||||
|  | ||||
| 		if (blah == ZT_EVENT_TIMER_PING) { | ||||
| #if 0 | ||||
| 			ast_log(LOG_DEBUG, "Calling private function\n"); | ||||
| 			ast_log(LOG_NOTICE, "Oooh, there's a PING!\n"); | ||||
| #endif			 | ||||
| 			func(data); | ||||
| 		} else { | ||||
| 			blah = 0; | ||||
| 			ast_mutex_lock(&chan->lock); | ||||
| 			ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah); | ||||
| 			chan->timingdata = NULL; | ||||
| 			if (!chan->pvt->readq || !chan->pvt->readq->next) { | ||||
| 				/* Acknowledge PONG unless we need it again */ | ||||
| #if 0 | ||||
| 				ast_log(LOG_NOTICE, "Sending a PONG!\n"); | ||||
| #endif				 | ||||
| 				if (ioctl(chan->timingfd, ZT_TIMERPONG, &blah)) { | ||||
| 					ast_log(LOG_WARNING, "Failed to pong timer on '%s': %s\n", chan->name, strerror(errno)); | ||||
| 				} | ||||
| 			} | ||||
| 		} else if (blah == ZT_EVENT_TIMER_EXPIRED) { | ||||
| 			ioctl(chan->timingfd, ZT_TIMERACK, &blah); | ||||
| 			func = chan->timingfunc; | ||||
| 			data = chan->timingdata; | ||||
| 			ast_mutex_unlock(&chan->lock); | ||||
| 		} | ||||
| 		f =  &null_frame; | ||||
| 		return f; | ||||
| 			if (func) { | ||||
| #if 0 | ||||
| 				ast_log(LOG_DEBUG, "Calling private function\n"); | ||||
| #endif			 | ||||
| 				func(data); | ||||
| 			} else { | ||||
| 				blah = 0; | ||||
| 				ast_mutex_lock(&chan->lock); | ||||
| 				ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah); | ||||
| 				chan->timingdata = NULL; | ||||
| 				ast_mutex_unlock(&chan->lock); | ||||
| 			} | ||||
| 			f =  &null_frame; | ||||
| 			return f; | ||||
| 		} else | ||||
| 			ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name); | ||||
| 	} | ||||
| #endif | ||||
| 	/* Check for pending read queue */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user