mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-01 19:43:03 +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:
78
channel.c
78
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
|
||||
/* 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