Adapt rtpoll and friends to Windows by replacing timespec with timeval and
authorPierre Ossman <ossman@cendio.se>
Wed, 3 Oct 2007 14:43:56 +0000 (14:43 +0000)
committerPierre Ossman <ossman@cendio.se>
Wed, 3 Oct 2007 14:43:56 +0000 (14:43 +0000)
add a fallback when clock_gettime() isn't available.

git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1926 fefdeb5f-60dc-0310-8127-8f9354f1896f

configure.ac
src/modules/module-combine.c
src/modules/module-null-sink.c
src/pulsecore/rtclock.c
src/pulsecore/rtclock.h
src/pulsecore/rtpoll.c
src/pulsecore/rtpoll.h

index b22a990..152cd51 100644 (file)
@@ -271,9 +271,10 @@ AC_CHECK_FUNCS([lrintf strtof])
 AC_FUNC_FORK
 AC_FUNC_GETGROUPS
 AC_FUNC_SELECT_ARGTYPES
-AC_CHECK_FUNCS([chmod chown getaddrinfo getgrgid_r getpwuid_r gettimeofday \
-    getuid inet_ntop inet_pton nanosleep pipe posix_fadvise posix_madvise \
-    posix_memalign setpgid setsid shm_open sigaction sleep sysconf])
+AC_CHECK_FUNCS([chmod chown clock_gettime getaddrinfo getgrgid_r \
+    getpwuid_r gettimeofday getuid inet_ntop inet_pton mlock nanosleep \
+    pipe posix_fadvise posix_madvise posix_memalign setpgid setsid shm_open \
+    sigaction sleep sysconf])
 AC_CHECK_FUNCS([mkfifo], [HAVE_MKFIFO=1], [HAVE_MKFIFO=0])
 
 AM_CONDITIONAL(HAVE_MKFIFO, test "x$HAVE_MKFIFO" = "x1")
index 447f41c..665bf9d 100644 (file)
@@ -118,7 +118,7 @@ struct userdata {
 
     pa_resample_method_t resample_method;
 
-    struct timespec adjust_timestamp;
+    struct timeval adjust_timestamp;
 
     struct output *master;
     pa_idxset* outputs; /* managed in main context */
@@ -126,7 +126,7 @@ struct userdata {
     struct {
         PA_LLIST_HEAD(struct output, active_outputs); /* managed in IO thread context */
         pa_atomic_t running;  /* we cache that value here, so that every thread can query it cheaply */
-        struct timespec timestamp;
+        struct timeval timestamp;
         pa_bool_t in_null_mode;
     } thread_info;
 };
@@ -247,17 +247,17 @@ static void thread_func(void *userdata) {
 
         /* If no outputs are connected, render some data and drop it immediately. */
         if (u->sink->thread_info.state == PA_SINK_RUNNING && !u->thread_info.active_outputs) {
-            struct timespec now;
+            struct timeval now;
 
             pa_rtclock_get(&now);
 
-            if (!u->thread_info.in_null_mode || pa_timespec_cmp(&u->thread_info.timestamp, &now) <= 0) {
+            if (!u->thread_info.in_null_mode || pa_timeval_cmp(&u->thread_info.timestamp, &now) <= 0) {
                 pa_sink_skip(u->sink, u->block_size);
 
                 if (!u->thread_info.in_null_mode)
                     u->thread_info.timestamp = now;
 
-                pa_timespec_add(&u->thread_info.timestamp, pa_bytes_to_usec(u->block_size, &u->sink->sample_spec));
+                pa_timeval_add(&u->thread_info.timestamp, pa_bytes_to_usec(u->block_size, &u->sink->sample_spec));
             }
 
             pa_rtpoll_set_timer_absolute(u->rtpoll, &u->thread_info.timestamp);
@@ -563,10 +563,10 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
              * sink_get_latency_cb() below */
 
             if (u->thread_info.in_null_mode) {
-                struct timespec now;
+                struct timeval now;
 
-                if (pa_timespec_cmp(&u->thread_info.timestamp, pa_rtclock_get(&now)) > 0) {
-                    *((pa_usec_t*) data) = pa_timespec_diff(&u->thread_info.timestamp, &now);
+                if (pa_timeval_cmp(&u->thread_info.timestamp, pa_rtclock_get(&now)) > 0) {
+                    *((pa_usec_t*) data) = pa_timeval_diff(&u->thread_info.timestamp, &now);
                     break;
                 }
             }
@@ -947,7 +947,7 @@ int pa__init(pa_module*m) {
     u->thread = NULL;
     u->resample_method = resample_method;
     u->outputs = pa_idxset_new(NULL, NULL);
-    pa_timespec_reset(&u->adjust_timestamp);
+    memset(&u->adjust_timestamp, 0, sizeof(u->adjust_timestamp));
     u->sink_new_slot = u->sink_unlink_slot = u->sink_state_changed_slot = NULL;
     PA_LLIST_HEAD_INIT(struct output, u->thread_info.active_outputs);
     pa_atomic_store(&u->thread_info.running, FALSE);
index 04df239..d993988 100644 (file)
@@ -75,7 +75,7 @@ struct userdata {
 
     size_t block_size;
     
-    struct timespec timestamp;
+    struct timeval timestamp;
 };
 
 static const char* const valid_modargs[] = {
@@ -100,14 +100,14 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
             break;
             
         case PA_SINK_MESSAGE_GET_LATENCY: {
-            struct timespec now;
+            struct timeval now;
     
             pa_rtclock_get(&now);
             
-            if (pa_timespec_cmp(&u->timestamp, &now) > 0)
+            if (pa_timeval_cmp(&u->timestamp, &now) > 0)
                 *((pa_usec_t*) data) = 0;
             else
-                *((pa_usec_t*) data) = pa_timespec_diff(&u->timestamp, &now);
+                *((pa_usec_t*) data) = pa_timeval_diff(&u->timestamp, &now);
             break;
         }
     }
@@ -132,13 +132,13 @@ static void thread_func(void *userdata) {
 
         /* Render some data and drop it immediately */
         if (u->sink->thread_info.state == PA_SINK_RUNNING) {
-            struct timespec now;
+            struct timeval now;
             
             pa_rtclock_get(&now);
 
-            if (pa_timespec_cmp(&u->timestamp, &now) <= 0) {
+            if (pa_timeval_cmp(&u->timestamp, &now) <= 0) {
                 pa_sink_skip(u->sink, u->block_size);
-                pa_timespec_add(&u->timestamp, pa_bytes_to_usec(u->block_size, &u->sink->sample_spec));
+                pa_timeval_add(&u->timestamp, pa_bytes_to_usec(u->block_size, &u->sink->sample_spec));
             }
 
             pa_rtpoll_set_timer_absolute(u->rtpoll, &u->timestamp);
index 7dd83b3..0d983f8 100644 (file)
 
 #include "rtclock.h"
 
-struct timespec *pa_timespec_store(struct timespec *a, pa_usec_t u) {
-    pa_assert(a);
+pa_usec_t pa_rtclock_age(const struct timeval *tv) {
+    struct timeval now;
+    pa_assert(tv);
 
-    a->tv_sec = u / PA_USEC_PER_SEC;
-
-    u -= (pa_usec_t) a->tv_sec * PA_USEC_PER_SEC;
-    
-    a->tv_nsec = u * 1000;
-
-    return a;
-}
-
-struct timespec *pa_timespec_reset(struct timespec *a) {
-    pa_assert(a);
-
-    a->tv_sec = a->tv_nsec = 0;
-    return a;
-}
-
-pa_usec_t pa_timespec_load(struct timespec *ts) {
-    pa_assert(ts);
-    
-    return (pa_usec_t) ts->tv_sec * PA_USEC_PER_SEC + (pa_usec_t) (ts->tv_nsec / 1000);
-}
-
-pa_usec_t pa_timespec_diff(const struct timespec *a, const struct timespec *b) {
-    pa_usec_t r;
-    
-    pa_assert(a);
-    pa_assert(b);
-
-    /* Check which whan is the earlier time and swap the two arguments if required. */
-    if (pa_timespec_cmp(a, b) < 0) {
-        const struct timespec *c;
-        c = a;
-        a = b;
-        b = c;
-    }
-
-    /* Calculate the second difference*/
-    r = ((pa_usec_t) a->tv_sec - b->tv_sec) * PA_USEC_PER_SEC;
-
-    /* Calculate the microsecond difference */
-    if (a->tv_nsec > b->tv_nsec)
-        r += (pa_usec_t) ((a->tv_nsec - b->tv_nsec) / 1000);
-    else if (a->tv_nsec < b->tv_nsec)
-        r -= (pa_usec_t) ((b->tv_nsec - a->tv_nsec) / 1000);
-
-    return r;
-}
-
-int pa_timespec_cmp(const struct timespec *a, const struct timespec *b) {
-    pa_assert(a);
-    pa_assert(b);
-
-    if (a->tv_sec < b->tv_sec)
-        return -1;
-
-    if (a->tv_sec > b->tv_sec)
-        return 1;
-
-    if (a->tv_nsec < b->tv_nsec)
-        return -1;
-
-    if (a->tv_nsec > b->tv_nsec)
-        return 1;
-
-    return 0;
+    return pa_timeval_diff(pa_rtclock_get(&now), tv);
 }
 
-struct timespec* pa_timespec_add(struct timespec *ts, pa_usec_t v) {
-    unsigned long secs;
-    pa_assert(ts);
-
-    secs = (unsigned long) (v/PA_USEC_PER_SEC);
-    ts->tv_sec += secs;
-    v -= ((pa_usec_t) secs) * PA_USEC_PER_SEC;
-
-    ts->tv_nsec += (long) (v*1000);
-
-    /* Normalize */
-    while (ts->tv_nsec >= PA_NSEC_PER_SEC) {
-        ts->tv_sec++;
-        ts->tv_nsec -= PA_NSEC_PER_SEC;
-    }
-
-    return ts;
-}
-
-pa_usec_t pa_rtclock_age(const struct timespec *ts) {
-    struct timespec now;
-    pa_assert(ts);
-
-    return pa_timespec_diff(pa_rtclock_get(&now), ts);
-}
-
-struct timespec *pa_rtclock_get(struct timespec *ts) {
+struct timeval *pa_rtclock_get(struct timeval *tv) {
+#ifdef HAVE_CLOCK_GETTIME
     static int no_monotonic = 0;
+    struct timespec ts;
 
     /* No locking or atomic ops for no_monotonic here */
-    
-    pa_assert(ts);
 
     if (!no_monotonic) {
 #ifdef CLOCK_MONOTONIC
-        if (clock_gettime(CLOCK_MONOTONIC, ts) >= 0)
-            return ts;
+        if (clock_gettime(CLOCK_MONOTONIC, &ts) >= 0)
+            goto out;
 #endif        
 
         no_monotonic = 1;
     }
 
     pa_assert_se(clock_gettime(CLOCK_REALTIME, ts) == 0);
-    return ts;
+
+out:
+    pa_assert(tv);
+
+    tv->tv_sec = ts.tv_sec;
+    tv->tv_usec = ts.tv_nsec / 1000;
+
+    return tv;
+
+#else /* HAVE_CLOCK_GETTIME */
+
+    return pa_gettimeofday(tv);
+
+#endif
 }
 
 int pa_rtclock_hrtimer(void) {
+#ifdef HAVE_CLOCK_GETTIME
     struct timespec ts;
     
 #ifdef CLOCK_MONOTONIC
@@ -161,5 +86,11 @@ int pa_rtclock_hrtimer(void) {
 
     pa_assert_se(clock_getres(CLOCK_REALTIME, &ts) == 0);
     return ts.tv_sec == 0 && ts.tv_nsec <= PA_HRTIMER_THRESHOLD_USEC*1000;
+
+#else /* HAVE_CLOCK_GETTIME */
+
+    return 0;
+
+#endif
 }
 
index cfc968f..0d232a0 100644 (file)
   USA.
 ***/
 
-#include <sys/types.h>
-#include <time.h>
+struct timeval;
 
-#include <pulse/sample.h>
+/* Something like pulse/timeval.h but based on CLOCK_MONOTONIC */
 
-/* Something like pulse/timeval.h but based on CLOCK_MONOTONIC and
- * timespec instead of timeval */
-
-struct timespec *pa_rtclock_get(struct timespec *ts);
-pa_usec_t pa_rtclock_age(const struct timespec *tv);
+struct timeval *pa_rtclock_get(struct timeval *ts);
+pa_usec_t pa_rtclock_age(const struct timeval *tv);
 int pa_rtclock_hrtimer(void);
 
-struct timespec *pa_timespec_store(struct timespec *a, pa_usec_t u);
-struct timespec *pa_timespec_reset(struct timespec *a);
-pa_usec_t pa_timespec_load(struct timespec *tv);
-struct timespec *pa_timespec_add(struct timespec *tv, pa_usec_t t);
-pa_usec_t pa_timespec_diff(const struct timespec *a, const struct timespec *b);
-int pa_timespec_cmp(const struct timespec *a, const struct timespec *b);
-
 /* timer with a resolution better than this are considered high-resolution */
 #define PA_HRTIMER_THRESHOLD_USEC 10
 
index de0ffa4..c81fcd1 100644 (file)
 #include <config.h>
 #endif
 
-#include <sys/utsname.h>
 #include <sys/types.h>
 #include <stdio.h>
 #include <signal.h>
 #include <string.h>
 #include <errno.h>
 
+#ifdef __linux__
+#include <sys/utsname.h>
+#endif
+
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#else
+#include <pulsecore/poll.h>
+#endif
+
 #include <pulse/xmalloc.h>
+#include <pulse/timeval.h>
 
 #include <pulsecore/core-error.h>
 #include <pulsecore/rtclock.h>
@@ -43,6 +53,8 @@
 #include <pulsecore/flist.h>
 #include <pulsecore/core-util.h>
 
+#include <pulsecore/winsock.h>
+
 #include "rtpoll.h"
 
 struct pa_rtpoll {
@@ -50,7 +62,7 @@ struct pa_rtpoll {
     unsigned n_pollfd_alloc, n_pollfd_used;
 
     pa_bool_t timer_enabled;
-    struct timespec next_elapse;
+    struct timeval next_elapse;
     pa_usec_t period;
 
     pa_bool_t scan_for_dead;
@@ -290,7 +302,7 @@ static void reset_all_revents(pa_rtpoll *p) {
 int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) {
     pa_rtpoll_item *i;
     int r = 0;
-    struct timespec timeout;
+    struct timeval timeout;
 
     pa_assert(p);
     pa_assert(!p->running);
@@ -357,15 +369,14 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) {
     /* Calculate timeout */
     if (!wait || p->quit) {
         timeout.tv_sec = 0;
-        timeout.tv_nsec = 0;
+        timeout.tv_usec = 0;
     } else if (p->timer_enabled) {
-        struct timespec now;
+        struct timeval now;
         pa_rtclock_get(&now);
 
-        if (pa_timespec_cmp(&p->next_elapse, &now) <= 0)
-            memset(&timeout, 0, sizeof(timeout));
-        else
-            pa_timespec_store(&timeout, pa_timespec_diff(&p->next_elapse, &now));
+        memset(&timeout, 0, sizeof(timeout));
+        if (pa_timeval_cmp(&p->next_elapse, &now) > 0)
+            pa_timeval_add(&timeout, pa_timeval_diff(&p->next_elapse, &now));
     }
 
     /* OK, now let's sleep */
@@ -380,7 +391,7 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) {
 #endif
 
 #endif
-        r = poll(p->pollfd, p->n_pollfd_used, p->timer_enabled ? (timeout.tv_sec*1000) + (timeout.tv_nsec / 1000000) : -1);
+        r = poll(p->pollfd, p->n_pollfd_used, p->timer_enabled ? (timeout.tv_sec*1000) + (timeout.tv_usec / 1000) : -1);
 
     if (r < 0) {
         if (errno == EAGAIN || errno == EINTR)
@@ -393,14 +404,14 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) {
 
     if (p->timer_enabled) {
         if (p->period > 0) {
-            struct timespec now;
+            struct timeval now;
             pa_rtclock_get(&now);
 
-            pa_timespec_add(&p->next_elapse, p->period);
+            pa_timeval_add(&p->next_elapse, p->period);
 
             /* Guarantee that the next timeout will happen in the future */
-            if (pa_timespec_cmp(&p->next_elapse, &now) < 0)
-                pa_timespec_add(&p->next_elapse, (pa_timespec_diff(&now, &p->next_elapse) / p->period + 1) * p->period);
+            if (pa_timeval_cmp(&p->next_elapse, &now) < 0)
+                pa_timeval_add(&p->next_elapse, (pa_timeval_diff(&now, &p->next_elapse) / p->period + 1) * p->period);
 
         } else
             p->timer_enabled = FALSE;
@@ -487,7 +498,7 @@ static void update_timer(pa_rtpoll *p) {
 #endif
 }
 
-void pa_rtpoll_set_timer_absolute(pa_rtpoll *p, const struct timespec *ts) {
+void pa_rtpoll_set_timer_absolute(pa_rtpoll *p, const struct timeval *ts) {
     pa_assert(p);
     pa_assert(ts);
 
@@ -503,7 +514,7 @@ void pa_rtpoll_set_timer_periodic(pa_rtpoll *p, pa_usec_t usec) {
 
     p->period = usec;
     pa_rtclock_get(&p->next_elapse);
-    pa_timespec_add(&p->next_elapse, usec);
+    pa_timeval_add(&p->next_elapse, usec);
     p->timer_enabled = TRUE;
 
     update_timer(p);
@@ -514,7 +525,7 @@ void pa_rtpoll_set_timer_relative(pa_rtpoll *p, pa_usec_t usec) {
 
     p->period = 0;
     pa_rtclock_get(&p->next_elapse);
-    pa_timespec_add(&p->next_elapse, usec);
+    pa_timeval_add(&p->next_elapse, usec);
     p->timer_enabled = TRUE;
 
     update_timer(p);
index a1242b3..d38d086 100644 (file)
@@ -24,7 +24,6 @@
   USA.
 ***/
 
-#include <poll.h>
 #include <sys/types.h>
 #include <limits.h>
 
@@ -75,7 +74,7 @@ void pa_rtpoll_install(pa_rtpoll *p);
  * cleanly. */
 int pa_rtpoll_run(pa_rtpoll *f, pa_bool_t wait);
 
-void pa_rtpoll_set_timer_absolute(pa_rtpoll *p, const struct timespec *ts);
+void pa_rtpoll_set_timer_absolute(pa_rtpoll *p, const struct timeval *ts);
 void pa_rtpoll_set_timer_periodic(pa_rtpoll *p, pa_usec_t usec);
 void pa_rtpoll_set_timer_relative(pa_rtpoll *p, pa_usec_t usec);
 void pa_rtpoll_set_timer_disabled(pa_rtpoll *p);