mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-03 11:25:35 +00:00
add infrastructure so that timing source can be a loadable module... next steps are to convert channel.c and chan_iax2.c to use this new API, and to move all the DAHDI-specific timing source code into a new res_timing_dahdi module
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@122062 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
112
include/asterisk/timing.h
Normal file
112
include/asterisk/timing.h
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Asterisk -- An open source telephony toolkit.
|
||||
*
|
||||
* Copyright (C) 2008, Digium, Inc.
|
||||
*
|
||||
* Kevin P. Fleming <kpfleming@digium.com>
|
||||
*
|
||||
* See http://www.asterisk.org for more information about
|
||||
* the Asterisk project. Please do not directly contact
|
||||
* any of the maintainers of this project for assistance;
|
||||
* the project provides a web site, mailing lists and IRC
|
||||
* channels for your use.
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License Version 2. See the LICENSE file
|
||||
* at the top of the source tree.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\file timing.h
|
||||
\brief Timing source management
|
||||
\author Kevin P. Fleming <kpfleming@digium.com>
|
||||
|
||||
Portions of Asterisk require a timing source, a periodic trigger
|
||||
for media handling activities. The functions in this file allow
|
||||
a loadable module to provide a timing source for Asterisk and its
|
||||
modules, so that those modules can request a 'timing handle' when
|
||||
they require one. These handles are file descriptors, which can be
|
||||
used with select() or poll().
|
||||
|
||||
The timing source used by Asterisk must provide the following
|
||||
features:
|
||||
|
||||
1) Periodic triggers, with a configurable interval (specified in
|
||||
millisconds).
|
||||
|
||||
2) Multiple outstanding triggers, each of which must be 'acked'
|
||||
to clear it. Triggers must also be 'ackable' in quantity.
|
||||
|
||||
3) Continuous trigger mode, which when enabled causes every call
|
||||
to poll() on the timer handle to immediately return.
|
||||
|
||||
4) Multiple 'event types', so that the code using the timer can
|
||||
know whether the wakeup it received was due to a periodic trigger
|
||||
or a continuous trigger.
|
||||
*/
|
||||
|
||||
#ifndef _ASTERISK_TIMING_H
|
||||
#define _ASTERISK_TIMING_H
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum ast_timing_event {
|
||||
AST_TIMING_EVENT_EXPIRED = 1,
|
||||
AST_TIMING_EVENT_CONTINUOUS = 2,
|
||||
};
|
||||
|
||||
struct ast_timing_functions {
|
||||
int (*timer_open)(unsigned int rate);
|
||||
void (*timer_close)(int handle);
|
||||
void (*timer_ack)(int handle, unsigned int quantity);
|
||||
int (*timer_enable_continuous)(int handle);
|
||||
int (*timer_disable_continuous)(int handle);
|
||||
enum ast_timing_event (*timer_get_event)(int handle);
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief Install a set of timing functions.
|
||||
\param funcs An instance of the \c ast_timing_functions structure with pointers
|
||||
to the functions provided by the timing implementation.
|
||||
\retval NULL on failure, or a handle to be passed to
|
||||
ast_uninstall_timing_functions() on success
|
||||
*/
|
||||
void *ast_install_timing_functions(struct ast_timing_functions *funcs);
|
||||
|
||||
/*!
|
||||
\brief Uninstall a previously-installed set of timing functions.
|
||||
\param handle The handle returned from a prior successful call to
|
||||
ast_install_timing_functions().
|
||||
\retval none
|
||||
*/
|
||||
void ast_uninstall_timing_functions(void *handle);
|
||||
|
||||
/*!
|
||||
\brief Open a timer handle.
|
||||
\param rate The rate at which the timer should trigger.
|
||||
\retval -1 on failure, or a positive integer on success
|
||||
*/
|
||||
int ast_timer_open(unsigned int rate);
|
||||
|
||||
/*!
|
||||
\brief Close a previously-opened timer handle.
|
||||
\param handle The timer handle to close.
|
||||
\retval none
|
||||
*/
|
||||
void ast_timer_close(int handle);
|
||||
|
||||
void ast_timer_ack(int handle, unsigned int quantity);
|
||||
|
||||
int ast_timer_enable_continuous(int handle);
|
||||
|
||||
int ast_timer_disable_continous(int handle);
|
||||
|
||||
enum ast_timing_event ast_timer_get_event(int handle);
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ASTERISK_TIMING_H */
|
@@ -30,7 +30,7 @@ OBJS= tcptls.o io.o sched.o logger.o frame.o loader.o config.o channel.o \
|
||||
cryptostub.o sha1.o http.o fixedjitterbuf.o abstract_jb.o \
|
||||
strcompat.o threadstorage.o dial.o event.o adsistub.o audiohook.o \
|
||||
astobj2.o hashtab.o global_datastores.o $(RESAMPLE_OBJS) version.o \
|
||||
features.o taskprocessor.o
|
||||
features.o taskprocessor.o timing.o
|
||||
|
||||
# we need to link in the objects statically, not as a library, because
|
||||
# otherwise modules will not have them available if none of the static
|
||||
|
174
main/timing.c
Normal file
174
main/timing.c
Normal file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Asterisk -- An open source telephony toolkit.
|
||||
*
|
||||
* Copyright (C) 2008, Digium, Inc.
|
||||
*
|
||||
* Kevin P. Fleming <kpfleming@digium.com>
|
||||
*
|
||||
* See http://www.asterisk.org for more information about
|
||||
* the Asterisk project. Please do not directly contact
|
||||
* any of the maintainers of this project for assistance;
|
||||
* the project provides a web site, mailing lists and IRC
|
||||
* channels for your use.
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License Version 2. See the LICENSE file
|
||||
* at the top of the source tree.
|
||||
*/
|
||||
|
||||
/*! \file
|
||||
*
|
||||
* \brief Timing source management
|
||||
*
|
||||
* \author Kevin P. Fleming <kpfleming@digium.com>
|
||||
*/
|
||||
|
||||
#include "asterisk.h"
|
||||
|
||||
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
||||
|
||||
#include "asterisk/timing.h"
|
||||
#include "asterisk/lock.h"
|
||||
|
||||
AST_MUTEX_DEFINE_STATIC(lock);
|
||||
|
||||
static struct ast_timing_functions timer_funcs;
|
||||
|
||||
void *ast_install_timing_functions(struct ast_timing_functions *funcs)
|
||||
{
|
||||
if (!funcs->timer_open ||
|
||||
!funcs->timer_close ||
|
||||
!funcs->timer_ack ||
|
||||
!funcs->timer_get_event ||
|
||||
!funcs->timer_enable_continuous ||
|
||||
!funcs->timer_disable_continuous) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ast_mutex_lock(&lock);
|
||||
|
||||
if (timer_funcs.timer_open) {
|
||||
ast_mutex_unlock(&lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
timer_funcs = *funcs;
|
||||
|
||||
ast_mutex_unlock(&lock);
|
||||
|
||||
return &timer_funcs;
|
||||
}
|
||||
|
||||
void ast_uninstall_timing_functions(void *handle)
|
||||
{
|
||||
ast_mutex_lock(&lock);
|
||||
|
||||
if (handle != &timer_funcs) {
|
||||
ast_mutex_unlock(&lock);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&timer_funcs, 0, sizeof(timer_funcs));
|
||||
|
||||
ast_mutex_unlock(&lock);
|
||||
}
|
||||
|
||||
int ast_timer_open(unsigned int rate)
|
||||
{
|
||||
int timer;
|
||||
|
||||
ast_mutex_lock(&lock);
|
||||
|
||||
if (!timer_funcs.timer_open) {
|
||||
ast_mutex_unlock(&lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
timer = timer_funcs.timer_open(rate);
|
||||
|
||||
ast_mutex_unlock(&lock);
|
||||
|
||||
return timer;
|
||||
}
|
||||
|
||||
void ast_timer_close(int timer)
|
||||
{
|
||||
ast_mutex_lock(&lock);
|
||||
|
||||
if (!timer_funcs.timer_close) {
|
||||
ast_mutex_unlock(&lock);
|
||||
return;
|
||||
}
|
||||
|
||||
timer_funcs.timer_close(timer);
|
||||
|
||||
ast_mutex_unlock(&lock);
|
||||
}
|
||||
|
||||
void ast_timer_ack(int handle, unsigned int quantity)
|
||||
{
|
||||
ast_mutex_lock(&lock);
|
||||
|
||||
if (!timer_funcs.timer_ack) {
|
||||
ast_mutex_unlock(&lock);
|
||||
return;
|
||||
}
|
||||
|
||||
timer_funcs.timer_ack(handle, quantity);
|
||||
|
||||
ast_mutex_unlock(&lock);
|
||||
}
|
||||
|
||||
int ast_timer_enable_continuous(int handle)
|
||||
{
|
||||
int result;
|
||||
|
||||
ast_mutex_lock(&lock);
|
||||
|
||||
if (!timer_funcs.timer_enable_continuous) {
|
||||
ast_mutex_unlock(&lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = timer_funcs.timer_enable_continuous(handle);
|
||||
|
||||
ast_mutex_unlock(&lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int ast_timer_disable_continous(int handle)
|
||||
{
|
||||
int result;
|
||||
|
||||
ast_mutex_lock(&lock);
|
||||
|
||||
if (!timer_funcs.timer_disable_continuous) {
|
||||
ast_mutex_unlock(&lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = timer_funcs.timer_disable_continuous(handle);
|
||||
|
||||
ast_mutex_unlock(&lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
enum ast_timing_event ast_timer_get_event(int handle)
|
||||
{
|
||||
enum ast_timing_event result;
|
||||
|
||||
ast_mutex_lock(&lock);
|
||||
|
||||
if (!timer_funcs.timer_get_event) {
|
||||
ast_mutex_unlock(&lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = timer_funcs.timer_get_event(handle);
|
||||
|
||||
ast_mutex_unlock(&lock);
|
||||
|
||||
return result;
|
||||
}
|
Reference in New Issue
Block a user