fix a few more XML documentation problems
[asterisk/asterisk.git] / res / res_timing_pthread.c
index ead2c2d..0afe9c9 100644 (file)
  * \brief pthread timing interface 
  */
 
  * \brief pthread timing interface 
  */
 
+/*** MODULEINFO
+       <conflict>res_timing_timerfd</conflict>
+       <conflict>res_timing_dahdi</conflict>
+ ***/
+
 #include "asterisk.h"
 
 ASTERISK_FILE_VERSION(__FILE__, "$Revision$");
 #include "asterisk.h"
 
 ASTERISK_FILE_VERSION(__FILE__, "$Revision$");
@@ -46,6 +51,7 @@ static void pthread_timer_ack(int handle, unsigned int quantity);
 static int pthread_timer_enable_continuous(int handle);
 static int pthread_timer_disable_continuous(int handle);
 static enum ast_timing_event pthread_timer_get_event(int handle);
 static int pthread_timer_enable_continuous(int handle);
 static int pthread_timer_disable_continuous(int handle);
 static enum ast_timing_event pthread_timer_get_event(int handle);
+static unsigned int pthread_timer_get_max_rate(int handle);
 
 static struct ast_timing_functions pthread_timing_functions = {
        .timer_open = pthread_timer_open,
 
 static struct ast_timing_functions pthread_timing_functions = {
        .timer_open = pthread_timer_open,
@@ -55,11 +61,11 @@ static struct ast_timing_functions pthread_timing_functions = {
        .timer_enable_continuous = pthread_timer_enable_continuous,
        .timer_disable_continuous = pthread_timer_disable_continuous,
        .timer_get_event = pthread_timer_get_event,
        .timer_enable_continuous = pthread_timer_enable_continuous,
        .timer_disable_continuous = pthread_timer_disable_continuous,
        .timer_get_event = pthread_timer_get_event,
+       .timer_get_max_rate = pthread_timer_get_max_rate,
 };
 
 };
 
-/* 1 tick / 20 ms */
-#define TIMING_INTERVAL 20
-#define MAX_RATE 50
+/* 1 tick / 10 ms */
+#define MAX_RATE 100
 
 static struct ao2_container *pthread_timers;
 #define PTHREAD_TIMER_BUCKETS 563
 
 static struct ao2_container *pthread_timers;
 #define PTHREAD_TIMER_BUCKETS 563
@@ -86,7 +92,7 @@ struct pthread_timer {
 };
 
 static void pthread_timer_destructor(void *obj);
 };
 
 static void pthread_timer_destructor(void *obj);
-static struct pthread_timer *find_timer(int handle, int unlink);
+static struct pthread_timer *find_timer(int handle, int unlinkobj);
 static void write_byte(int wr_fd);
 static void read_pipe(int rd_fd, unsigned int num, int clear);
 
 static void write_byte(int wr_fd);
 static void read_pipe(int rd_fd, unsigned int num, int clear);
 
@@ -103,6 +109,7 @@ static struct {
 static int pthread_timer_open(void)
 {
        struct pthread_timer *timer;
 static int pthread_timer_open(void)
 {
        struct pthread_timer *timer;
+       int fd;
 
        if (!(timer = ao2_alloc(sizeof(*timer), pthread_timer_destructor))) {
                errno = ENOMEM;
 
        if (!(timer = ao2_alloc(sizeof(*timer), pthread_timer_destructor))) {
                errno = ENOMEM;
@@ -126,7 +133,11 @@ static int pthread_timer_open(void)
        ao2_link(pthread_timers, timer);
        ao2_unlock(pthread_timers);
 
        ao2_link(pthread_timers, timer);
        ao2_unlock(pthread_timers);
 
-       return timer->pipe[PIPE_READ];
+       fd = timer->pipe[PIPE_READ];
+
+       ao2_ref(timer, -1);
+
+       return fd;
 }
 
 static void pthread_timer_close(int handle)
 }
 
 static void pthread_timer_close(int handle)
@@ -140,6 +151,23 @@ static void pthread_timer_close(int handle)
        ao2_ref(timer, -1);
 }
 
        ao2_ref(timer, -1);
 }
 
+static void set_state(struct pthread_timer *timer)
+{
+       unsigned int rate = timer->rate;
+
+       if (rate) {
+               timer->state = TIMER_STATE_TICKING;
+               timer->interval = roundf(1000.0 / ((float) rate));
+               timer->start = ast_tvnow();
+       } else {
+               timer->state = TIMER_STATE_IDLE;
+               timer->interval = 0;
+               timer->start = ast_tv(0, 0);
+       }
+
+       timer->tick_count = 0;
+}
+
 static int pthread_timer_set_rate(int handle, unsigned int rate)
 {
        struct pthread_timer *timer;
 static int pthread_timer_set_rate(int handle, unsigned int rate)
 {
        struct pthread_timer *timer;
@@ -158,10 +186,10 @@ static int pthread_timer_set_rate(int handle, unsigned int rate)
 
        ao2_lock(timer);
        timer->rate = rate;
 
        ao2_lock(timer);
        timer->rate = rate;
-       timer->state = rate ? TIMER_STATE_TICKING : TIMER_STATE_IDLE;
-       timer->interval = rate ? roundf(1000.0 / ((float) rate)) : 0;
-       timer->start = rate ? ast_tvnow() : ast_tv(0, 0);
-       timer->tick_count = 0;
+       if (timer->state != TIMER_STATE_CONTINUOUS) {
+               set_state(timer);
+       }
+       
        ao2_unlock(timer);
 
        ao2_ref(timer, -1);
        ao2_unlock(timer);
 
        ao2_ref(timer, -1);
@@ -218,7 +246,7 @@ static int pthread_timer_disable_continuous(int handle)
        }
 
        ao2_lock(timer);
        }
 
        ao2_lock(timer);
-       timer->state = timer->rate ? TIMER_STATE_TICKING : TIMER_STATE_IDLE;
+       set_state(timer);
        read_pipe(timer->pipe[PIPE_READ], 0, 1);
        ao2_unlock(timer);
 
        read_pipe(timer->pipe[PIPE_READ], 0, 1);
        ao2_unlock(timer);
 
@@ -245,7 +273,12 @@ static enum ast_timing_event pthread_timer_get_event(int handle)
        return res;
 }
 
        return res;
 }
 
-static struct pthread_timer *find_timer(int handle, int unlink)
+static unsigned int pthread_timer_get_max_rate(int handle)
+{
+       return MAX_RATE;
+}
+
+static struct pthread_timer *find_timer(int handle, int unlinkobj)
 {
        struct pthread_timer *timer;
        struct pthread_timer tmp_timer;
 {
        struct pthread_timer *timer;
        struct pthread_timer tmp_timer;
@@ -253,7 +286,7 @@ static struct pthread_timer *find_timer(int handle, int unlink)
 
        tmp_timer.pipe[PIPE_READ] = handle;
 
 
        tmp_timer.pipe[PIPE_READ] = handle;
 
-       if (unlink) {
+       if (unlinkobj) {
                flags |= OBJ_UNLINK;
        }
 
                flags |= OBJ_UNLINK;
        }
 
@@ -297,7 +330,7 @@ static int pthread_timer_cmp(void *obj, void *arg, int flags)
 {
        struct pthread_timer *timer1 = obj, *timer2 = arg;
 
 {
        struct pthread_timer *timer1 = obj, *timer2 = arg;
 
-       return (timer1->pipe[PIPE_READ] == timer2->pipe[PIPE_READ]) ? CMP_MATCH : 0;
+       return (timer1->pipe[PIPE_READ] == timer2->pipe[PIPE_READ]) ? CMP_MATCH | CMP_STOP : 0;
 }
 
 /*!
 }
 
 /*!
@@ -327,7 +360,6 @@ static int check_timer(struct pthread_timer *timer)
 
 static void read_pipe(int rd_fd, unsigned int quantity, int clear)
 {
 
 static void read_pipe(int rd_fd, unsigned int quantity, int clear)
 {
-
        ast_assert(quantity || clear);
 
        if (!quantity && clear) {
        ast_assert(quantity || clear);
 
        if (!quantity && clear) {
@@ -338,7 +370,7 @@ static void read_pipe(int rd_fd, unsigned int quantity, int clear)
                unsigned char buf[1024];
                ssize_t res;
                fd_set rfds;
                unsigned char buf[1024];
                ssize_t res;
                fd_set rfds;
-               struct timeval tv = {
+               struct timeval timeout = {
                        .tv_sec = 0,
                };
 
                        .tv_sec = 0,
                };
 
@@ -346,7 +378,7 @@ static void read_pipe(int rd_fd, unsigned int quantity, int clear)
                FD_ZERO(&rfds);
                FD_SET(rd_fd, &rfds);
 
                FD_ZERO(&rfds);
                FD_SET(rd_fd, &rfds);
 
-               if (select(rd_fd + 1, &rfds, NULL, NULL, &tv) != 1) {
+               if (select(rd_fd + 1, &rfds, NULL, NULL, &timeout) != 1) {
                        break;
                }
 
                        break;
                }
 
@@ -412,9 +444,9 @@ static void *do_timing(void *arg)
        while (!timing_thread.stop) {
                struct timespec ts = { 0, };
 
        while (!timing_thread.stop) {
                struct timespec ts = { 0, };
 
-               ao2_callback(pthread_timers, 0, run_timer, NULL);
+               ao2_callback(pthread_timers, OBJ_NODATA, run_timer, NULL);
 
 
-               next_wakeup = ast_tvadd(next_wakeup, ast_tv(0, 10000));
+               next_wakeup = ast_tvadd(next_wakeup, ast_tv(0, 5000));
 
                ts.tv_sec = next_wakeup.tv_sec;
                ts.tv_nsec = next_wakeup.tv_usec * 1000;
 
                ts.tv_sec = next_wakeup.tv_sec;
                ts.tv_nsec = next_wakeup.tv_usec * 1000;