Merged revisions 184762 via svnmerge from

https://origsvn.digium.com/svn/asterisk/trunk

........
  r184762 | kpfleming | 2009-03-27 14:10:32 -0500 (Fri, 27 Mar 2009) | 12 lines
  
  Improve timing interface to remember which provider provided a timer
  
  The ability to load/unload timing interfaces is nice, but it means that when a timer is allocated, it may come from provider A, but later provider B becomes the 'preferred' provider. If this happens, all timer API calls on the timer that was provided by provider A will actually be handed to provider B, which will say WTF and return an error.
  
  This patch changes the timer API to include a pointer to the provider of the timer handle so that future operations on the timer will be forwarded to the proper provider.
  
  (closes issue #14697)
  Reported by: moy
  
  Review: http://reviewboard.digium.com/r/211/
........


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.6.1@184765 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Kevin P. Fleming
2009-03-27 19:17:22 +00:00
parent ec2800dac7
commit ad618c6c4f
5 changed files with 124 additions and 139 deletions

View File

@@ -806,17 +806,19 @@ struct ast_channel *ast_channel_alloc(int needqueue, int state, const char *cid_
#endif
}
tmp->timingfd = ast_timer_open();
if (tmp->timingfd > -1) {
if ((tmp->timer = ast_timer_open())) {
needqueue = 0;
tmp->timingfd = ast_timer_fd(tmp->timer);
} else {
tmp->timingfd = -1;
}
if (needqueue) {
if (pipe(tmp->alertpipe)) {
ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe!\n");
alertpipe_failed:
if (tmp->timingfd > -1) {
ast_timer_close(tmp->timingfd);
if (tmp->timer) {
ast_timer_close(tmp->timer);
}
sched_context_destroy(tmp->sched);
@@ -1005,7 +1007,7 @@ static int __ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin, in
chan->name, f->frametype, f->subclass, qlen, strerror(errno));
}
} else if (chan->timingfd > -1) {
ast_timer_enable_continuous(chan->timingfd);
ast_timer_enable_continuous(chan->timer);
} else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
pthread_kill(chan->blocker, SIGURG);
}
@@ -1355,8 +1357,9 @@ void ast_channel_free(struct ast_channel *chan)
close(fd);
if ((fd = chan->alertpipe[1]) > -1)
close(fd);
if ((fd = chan->timingfd) > -1)
ast_timer_close(fd);
if (chan->timer) {
ast_timer_close(chan->timer);
}
#ifdef HAVE_EPOLL
for (i = 0; i < AST_MAX_FDS; i++) {
if (chan->epfd_data[i])
@@ -2298,13 +2301,13 @@ int ast_settimeout(struct ast_channel *c, unsigned int rate, int (*func)(const v
data = NULL;
}
if (rate && rate > (max_rate = ast_timer_get_max_rate(c->timingfd))) {
if (rate && rate > (max_rate = ast_timer_get_max_rate(c->timer))) {
real_rate = max_rate;
}
ast_debug(1, "Scheduling timer at (%u requested / %u actual) timer ticks per second\n", rate, real_rate);
res = ast_timer_set_rate(c->timingfd, real_rate);
res = ast_timer_set_rate(c->timer, real_rate);
c->timingfunc = func;
c->timingdata = data;
@@ -2557,11 +2560,11 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
ast_clear_flag(chan, AST_FLAG_EXCEPTION);
res = ast_timer_get_event(chan->timingfd);
res = ast_timer_get_event(chan->timer);
switch (res) {
case AST_TIMING_EVENT_EXPIRED:
ast_timer_ack(chan->timingfd, 1);
ast_timer_ack(chan->timer, 1);
if (chan->timingfunc) {
/* save a copy of func/data before unlocking the channel */
@@ -2571,7 +2574,7 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
ast_channel_unlock(chan);
func(data);
} else {
ast_timer_set_rate(chan->timingfd, 0);
ast_timer_set_rate(chan->timer, 0);
chan->fdno = -1;
ast_channel_unlock(chan);
}
@@ -2582,7 +2585,7 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
case AST_TIMING_EVENT_CONTINUOUS:
if (AST_LIST_EMPTY(&chan->readq) ||
!AST_LIST_NEXT(AST_LIST_FIRST(&chan->readq), frame_list)) {
ast_timer_disable_continuous(chan->timingfd);
ast_timer_disable_continuous(chan->timer);
}
break;
}