diff --git a/Makefile b/Makefile index 160e498968126300a03512a13a40ba4ee6c1d46e..d157814eea24d38ac83b946c421ac3aebe3ac07d 100755 --- a/Makefile +++ b/Makefile @@ -91,7 +91,7 @@ ifeq (${OSARCH},OpenBSD) CFLAGS+=-pthread endif -#CFLAGS+=$(shell if [ -f /usr/include/linux/zaptel.h ]; then echo "-DZAPTEL_OPTIMIZATIONS"; fi) +CFLAGS+=$(shell if [ -f /usr/include/linux/zaptel.h ]; then echo "-DZAPTEL_OPTIMIZATIONS"; fi) LIBEDIT=editline/libedit.a diff --git a/channel.c b/channel.c index 2127a46bdea8b6382aabe2ddff27b82a1ac1a798..f66d6174f02def613096c1d144c501a3903f87b9 100755 --- a/channel.c +++ b/channel.c @@ -938,13 +938,19 @@ char ast_waitfordigit(struct ast_channel *c, int ms) return result; } -int ast_settimeout(struct ast_channel *c, int ms) +int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data) { int res = -1; #ifdef ZAPTEL_OPTIMIZATIONS if (c->timingfd > -1) { - ms *= 8; - res = ioctl(c->timingfd, ZT_TIMERCONFIG, &ms); + if (!func) { + samples = 0; + data = 0; + } + ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples); + res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples); + c->timingfunc = func; + c->timingdata = data; } #endif return res; @@ -983,6 +989,10 @@ struct ast_frame *ast_read(struct ast_channel *chan) { struct ast_frame *f = NULL; int blah; +#ifdef ZAPTEL_OPTIMIZATIONS + int (*func)(void *); + void *data; +#endif static struct ast_frame null_frame = { AST_FRAME_NULL, @@ -1027,10 +1037,18 @@ struct ast_frame *ast_read(struct ast_channel *chan) chan->exception = 0; blah = -1; ioctl(chan->timingfd, ZT_TIMERACK, &blah); - blah = 0; - ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah); - f = &null_frame; + func = chan->timingfunc; + data = chan->timingdata; pthread_mutex_unlock(&chan->lock); + if (func) { + func(data); + } else { + blah = 0; + pthread_mutex_lock(&chan->lock); + ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah); + pthread_mutex_unlock(&chan->lock); + } + f = &null_frame; return f; } #endif diff --git a/file.c b/file.c index 0c30afdceaf60359e62f82942b9896f07f4b7cea..6b199f9823a3f45871dd9158df2f15c672bb07ab 100755 --- a/file.c +++ b/file.c @@ -508,16 +508,26 @@ static int ast_readaudio_callback(void *data) if (ast_write(s->owner, fr)) { ast_log(LOG_WARNING, "Failed to write frame\n"); s->owner->streamid = -1; +#ifdef ZAPTEL_OPTIMIZATIONS + ast_settimeout(s->owner, 0, NULL, NULL); +#endif return 0; } } else { /* Stream has finished */ s->owner->streamid = -1; +#ifdef ZAPTEL_OPTIMIZATIONS + ast_settimeout(s->owner, 0, NULL, NULL); +#endif return 0; } } if (whennext != s->lasttimeout) { +#ifdef ZAPTEL_OPTIMIZATIONS + ast_settimeout(s->owner, whennext, ast_readaudio_callback, s); +#else s->owner->streamid = ast_sched_add(s->owner->sched, whennext/8, ast_readaudio_callback, s); +#endif s->lasttimeout = whennext; return 0; } @@ -606,6 +616,9 @@ int ast_closestream(struct ast_filestream *f) if (f->owner->streamid > -1) ast_sched_del(f->owner->sched, f->owner->streamid); f->owner->streamid = -1; +#ifdef ZAPTEL_OPTIMIZATIONS + ast_settimeout(f->owner, 0, NULL, NULL); +#endif } else { f->owner->vstream = NULL; if (f->owner->vstreamid > -1) @@ -766,15 +779,15 @@ char ast_waitstream(struct ast_channel *c, char *breakon) struct ast_frame *fr; while(c->stream) { res = ast_sched_wait(c->sched); - if (res < 0) { + if ((res < 0) && !c->timingfunc) { if (c->stream) ast_closestream(c->stream); if (c->vstream) ast_closestream(c->vstream); break; } - /* Setup timeout if supported */ - ast_settimeout(c, res); + if (res < 0) + res = 1000; res = ast_waitfor(c, res); if (res < 0) { ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); @@ -832,7 +845,6 @@ char ast_waitstream_fr(struct ast_channel *c, char *breakon, char *forward, char ast_closestream(c->vstream); break; } - ast_settimeout(c, res); res = ast_waitfor(c, res); if (res < 0) { ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); @@ -899,7 +911,6 @@ char ast_waitstream_full(struct ast_channel *c, char *breakon, int audiofd, int ast_closestream(c->vstream); break; } - ast_settimeout(c, ms); rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); if (!rchan && (outfd < 0) && (ms)) { ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); diff --git a/formats/format_vox.c b/formats/format_vox.c index 095ca17032bbc72441e9036fe9a1c7945e16741e..00c8e16ebf1089cb89062e413d379faf2f97971b 100755 --- a/formats/format_vox.c +++ b/formats/format_vox.c @@ -48,7 +48,6 @@ struct ast_filestream { }; -static struct ast_filestream *glist = NULL; static pthread_mutex_t vox_lock = AST_MUTEX_INITIALIZER; static int glistcnt = 0; diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index c7867b144a75753a72c76d28152658eba2111fa9..107e70da4d38db2359d5c552e6d4cb1689c3654e 100755 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -125,7 +125,8 @@ struct ast_channel { /*! Timing fd */ int timingfd; - + int (*timingfunc)(void *data); + void *timingdata; /*! State of line -- Don't write directly, use ast_setstate */ int _state; @@ -695,8 +696,8 @@ int ast_autoservice_start(struct ast_channel *chan); int ast_autoservice_stop(struct ast_channel *chan); /* If built with zaptel optimizations, force a scheduled expiration on the - timer fd */ -int ast_settimeout(struct ast_channel *c, int ms); + timer fd, at which point we call the callback function / data */ +int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data); /* Transfer a channel (if supported). Returns -1 on error, 0 if not supported and 1 if supported and requested */ diff --git a/include/asterisk/file.h b/include/asterisk/file.h index 418564249c8a12668a02a079a872d1f5727f8c32..da3723dac4499e4739336550ff5b6025accda28f 100755 --- a/include/asterisk/file.h +++ b/include/asterisk/file.h @@ -259,7 +259,7 @@ int ast_stream_rewind(struct ast_filestream *fs, long ms); */ long ast_tellstream(struct ast_filestream *fs); -#define AST_RESERVED_POINTERS 12 +#define AST_RESERVED_POINTERS 20 #if defined(__cplusplus) || defined(c_plusplus) }