]> code.delx.au - pulseaudio/blobdiff - src/pulse/mainloop.c
volume: when passing NULL as channel map to pa_cvolume_scale_mask() handle this the...
[pulseaudio] / src / pulse / mainloop.c
index aaed3caf1a32f33cb60a844bf81cab5f68d74751..93a4742d0263de8ae12fab62834bbe2bebee489a 100644 (file)
@@ -6,7 +6,7 @@
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2 of the License,
+  by the Free Software Foundation; either version 2.1 of the License,
   or (at your option) any later version.
 
   PulseAudio is distributed in the hope that it will be useful, but
   or (at your option) any later version.
 
   PulseAudio is distributed in the hope that it will be useful, but
 #include <pulsecore/pipe.h>
 #endif
 
 #include <pulsecore/pipe.h>
 #endif
 
+#include <pulse/i18n.h>
+#include <pulse/rtclock.h>
 #include <pulse/timeval.h>
 #include <pulse/xmalloc.h>
 
 #include <pulse/timeval.h>
 #include <pulse/xmalloc.h>
 
+#include <pulsecore/core-rtclock.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/llist.h>
 #include <pulsecore/log.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/llist.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 
 #include "mainloop.h"
 #include <pulsecore/macro.h>
 
 #include "mainloop.h"
+#include "internal.h"
 
 struct pa_io_event {
     pa_mainloop *mainloop;
 
 struct pa_io_event {
     pa_mainloop *mainloop;
-    int dead;
+    pa_bool_t dead:1;
 
     int fd;
     pa_io_event_flags_t events;
 
     int fd;
     pa_io_event_flags_t events;
@@ -71,10 +75,10 @@ struct pa_io_event {
 
 struct pa_time_event {
     pa_mainloop *mainloop;
 
 struct pa_time_event {
     pa_mainloop *mainloop;
-    int dead;
+    pa_bool_t dead:1;
 
 
-    int enabled;
-    struct timeval timeval;
+    pa_bool_t enabled:1;
+    pa_usec_t time;
 
     pa_time_event_cb_t callback;
     void *userdata;
 
     pa_time_event_cb_t callback;
     void *userdata;
@@ -85,9 +89,9 @@ struct pa_time_event {
 
 struct pa_defer_event {
     pa_mainloop *mainloop;
 
 struct pa_defer_event {
     pa_mainloop *mainloop;
-    int dead;
+    pa_bool_t dead:1;
 
 
-    int enabled;
+    pa_bool_t enabled:1;
 
     pa_defer_event_cb_t callback;
     void *userdata;
 
     pa_defer_event_cb_t callback;
     void *userdata;
@@ -101,22 +105,24 @@ struct pa_mainloop {
     PA_LLIST_HEAD(pa_time_event, time_events);
     PA_LLIST_HEAD(pa_defer_event, defer_events);
 
     PA_LLIST_HEAD(pa_time_event, time_events);
     PA_LLIST_HEAD(pa_defer_event, defer_events);
 
-    int n_enabled_defer_events, n_enabled_time_events, n_io_events;
-    int io_events_please_scan, time_events_please_scan, defer_events_please_scan;
+    unsigned n_enabled_defer_events, n_enabled_time_events, n_io_events;
+    unsigned io_events_please_scan, time_events_please_scan, defer_events_please_scan;
 
 
+    pa_bool_t rebuild_pollfds:1;
     struct pollfd *pollfds;
     unsigned max_pollfds, n_pollfds;
     struct pollfd *pollfds;
     unsigned max_pollfds, n_pollfds;
-    int rebuild_pollfds;
 
     int prepared_timeout;
     pa_time_event *cached_next_time_event;
 
 
     int prepared_timeout;
     pa_time_event *cached_next_time_event;
 
-    int quit, retval;
     pa_mainloop_api api;
 
     pa_mainloop_api api;
 
+    int retval;
+    pa_bool_t quit:1;
+
+    pa_bool_t wakeup_requested:1;
     int wakeup_pipe[2];
     int wakeup_pipe_type;
     int wakeup_pipe[2];
     int wakeup_pipe_type;
-    int wakeup_requested;
 
     enum {
         STATE_PASSIVE,
 
     enum {
         STATE_PASSIVE,
@@ -132,11 +138,11 @@ struct pa_mainloop {
 };
 
 static short map_flags_to_libc(pa_io_event_flags_t flags) {
 };
 
 static short map_flags_to_libc(pa_io_event_flags_t flags) {
-    return
-        (flags & PA_IO_EVENT_INPUT ? POLLIN : 0) |
-        (flags & PA_IO_EVENT_OUTPUT ? POLLOUT : 0) |
-        (flags & PA_IO_EVENT_ERROR ? POLLERR : 0) |
-        (flags & PA_IO_EVENT_HANGUP ? POLLHUP : 0);
+    return (short)
+        ((flags & PA_IO_EVENT_INPUT ? POLLIN : 0) |
+         (flags & PA_IO_EVENT_OUTPUT ? POLLOUT : 0) |
+         (flags & PA_IO_EVENT_ERROR ? POLLERR : 0) |
+         (flags & PA_IO_EVENT_HANGUP ? POLLHUP : 0));
 }
 
 static pa_io_event_flags_t map_flags_from_libc(short flags) {
 }
 
 static pa_io_event_flags_t map_flags_from_libc(short flags) {
@@ -168,7 +174,7 @@ static pa_io_event* mainloop_io_new(
 
     e = pa_xnew(pa_io_event, 1);
     e->mainloop = m;
 
     e = pa_xnew(pa_io_event, 1);
     e->mainloop = m;
-    e->dead = 0;
+    e->dead = FALSE;
 
     e->fd = fd;
     e->events = events;
 
     e->fd = fd;
     e->events = events;
@@ -193,13 +199,13 @@ static pa_io_event* mainloop_io_new(
                     SELECT_TYPE_ARG5 &tv) == -1) &&
              (WSAGetLastError() == WSAENOTSOCK)) {
             pa_log_warn("Cannot monitor non-socket file descriptors.");
                     SELECT_TYPE_ARG5 &tv) == -1) &&
              (WSAGetLastError() == WSAENOTSOCK)) {
             pa_log_warn("Cannot monitor non-socket file descriptors.");
-            e->dead = 1;
+            e->dead = TRUE;
         }
     }
 #endif
 
     PA_LLIST_PREPEND(pa_io_event, m->io_events, e);
         }
     }
 #endif
 
     PA_LLIST_PREPEND(pa_io_event, m->io_events, e);
-    m->rebuild_pollfds = 1;
+    m->rebuild_pollfds = TRUE;
     m->n_io_events ++;
 
     pa_mainloop_wakeup(m);
     m->n_io_events ++;
 
     pa_mainloop_wakeup(m);
@@ -219,7 +225,7 @@ static void mainloop_io_enable(pa_io_event *e, pa_io_event_flags_t events) {
     if (e->pollfd)
         e->pollfd->events = map_flags_to_libc(events);
     else
     if (e->pollfd)
         e->pollfd->events = map_flags_to_libc(events);
     else
-        e->mainloop->rebuild_pollfds = 1;
+        e->mainloop->rebuild_pollfds = TRUE;
 
     pa_mainloop_wakeup(e->mainloop);
 }
 
     pa_mainloop_wakeup(e->mainloop);
 }
@@ -228,11 +234,11 @@ static void mainloop_io_free(pa_io_event *e) {
     pa_assert(e);
     pa_assert(!e->dead);
 
     pa_assert(e);
     pa_assert(!e->dead);
 
-    e->dead = 1;
+    e->dead = TRUE;
     e->mainloop->io_events_please_scan ++;
 
     e->mainloop->n_io_events --;
     e->mainloop->io_events_please_scan ++;
 
     e->mainloop->n_io_events --;
-    e->mainloop->rebuild_pollfds = 1;
+    e->mainloop->rebuild_pollfds = TRUE;
 
     pa_mainloop_wakeup(e->mainloop);
 }
 
     pa_mainloop_wakeup(e->mainloop);
 }
@@ -261,9 +267,9 @@ static pa_defer_event* mainloop_defer_new(
 
     e = pa_xnew(pa_defer_event, 1);
     e->mainloop = m;
 
     e = pa_xnew(pa_defer_event, 1);
     e->mainloop = m;
-    e->dead = 0;
+    e->dead = FALSE;
 
 
-    e->enabled = 1;
+    e->enabled = TRUE;
     m->n_enabled_defer_events++;
 
     e->callback = callback;
     m->n_enabled_defer_events++;
 
     e->callback = callback;
@@ -296,13 +302,13 @@ static void mainloop_defer_free(pa_defer_event *e) {
     pa_assert(e);
     pa_assert(!e->dead);
 
     pa_assert(e);
     pa_assert(!e->dead);
 
-    e->dead = 1;
+    e->dead = TRUE;
     e->mainloop->defer_events_please_scan ++;
 
     if (e->enabled) {
         pa_assert(e->mainloop->n_enabled_defer_events > 0);
         e->mainloop->n_enabled_defer_events--;
     e->mainloop->defer_events_please_scan ++;
 
     if (e->enabled) {
         pa_assert(e->mainloop->n_enabled_defer_events > 0);
         e->mainloop->n_enabled_defer_events--;
-        e->enabled = 0;
+        e->enabled = FALSE;
     }
 }
 
     }
 }
 
@@ -314,6 +320,23 @@ static void mainloop_defer_set_destroy(pa_defer_event *e, pa_defer_event_destroy
 }
 
 /* Time events */
 }
 
 /* Time events */
+static pa_usec_t timeval_load(const struct timeval *tv) {
+    pa_bool_t is_rtclock;
+    struct timeval ttv;
+
+    if (!tv)
+        return PA_USEC_INVALID;
+
+    ttv = *tv;
+    is_rtclock = !!(ttv.tv_usec & PA_TIMEVAL_RTCLOCK);
+    ttv.tv_usec &= ~PA_TIMEVAL_RTCLOCK;
+
+    if (!is_rtclock)
+        pa_rtclock_from_wallclock(&ttv);
+
+    return pa_timeval_load(&ttv);
+}
+
 static pa_time_event* mainloop_time_new(
         pa_mainloop_api*a,
         const struct timeval *tv,
 static pa_time_event* mainloop_time_new(
         pa_mainloop_api*a,
         const struct timeval *tv,
@@ -322,27 +345,30 @@ static pa_time_event* mainloop_time_new(
 
     pa_mainloop *m;
     pa_time_event *e;
 
     pa_mainloop *m;
     pa_time_event *e;
+    pa_usec_t t;
 
     pa_assert(a);
     pa_assert(a->userdata);
     pa_assert(callback);
 
 
     pa_assert(a);
     pa_assert(a->userdata);
     pa_assert(callback);
 
+    t = timeval_load(tv);
+
     m = a->userdata;
     pa_assert(a == &m->api);
 
     e = pa_xnew(pa_time_event, 1);
     e->mainloop = m;
     m = a->userdata;
     pa_assert(a == &m->api);
 
     e = pa_xnew(pa_time_event, 1);
     e->mainloop = m;
-    e->dead = 0;
+    e->dead = FALSE;
 
 
-    if ((e->enabled = !!tv)) {
-        e->timeval = *tv;
+    if ((e->enabled = (t != PA_USEC_INVALID))) {
+        e->time = t;
 
         m->n_enabled_time_events++;
 
         if (m->cached_next_time_event) {
             pa_assert(m->cached_next_time_event->enabled);
 
 
         m->n_enabled_time_events++;
 
         if (m->cached_next_time_event) {
             pa_assert(m->cached_next_time_event->enabled);
 
-            if (pa_timeval_cmp(tv, &m->cached_next_time_event->timeval) < 0)
+            if (t < m->cached_next_time_event->time)
                 m->cached_next_time_event = e;
         }
     }
                 m->cached_next_time_event = e;
         }
     }
@@ -360,24 +386,30 @@ static pa_time_event* mainloop_time_new(
 }
 
 static void mainloop_time_restart(pa_time_event *e, const struct timeval *tv) {
 }
 
 static void mainloop_time_restart(pa_time_event *e, const struct timeval *tv) {
+    pa_bool_t valid;
+    pa_usec_t t;
+
     pa_assert(e);
     pa_assert(!e->dead);
 
     pa_assert(e);
     pa_assert(!e->dead);
 
-    if (e->enabled && !tv) {
+    t = timeval_load(tv);
+
+    valid = (t != PA_USEC_INVALID);
+    if (e->enabled && !valid) {
         pa_assert(e->mainloop->n_enabled_time_events > 0);
         e->mainloop->n_enabled_time_events--;
         pa_assert(e->mainloop->n_enabled_time_events > 0);
         e->mainloop->n_enabled_time_events--;
-    } else if (!e->enabled && tv)
+    } else if (!e->enabled && valid)
         e->mainloop->n_enabled_time_events++;
 
         e->mainloop->n_enabled_time_events++;
 
-    if ((e->enabled = !!tv)) {
-        e->timeval = *tv;
+    if ((e->enabled = valid)) {
+        e->time = t;
         pa_mainloop_wakeup(e->mainloop);
     }
 
     if (e->mainloop->cached_next_time_event && e->enabled) {
         pa_assert(e->mainloop->cached_next_time_event->enabled);
 
         pa_mainloop_wakeup(e->mainloop);
     }
 
     if (e->mainloop->cached_next_time_event && e->enabled) {
         pa_assert(e->mainloop->cached_next_time_event->enabled);
 
-        if (pa_timeval_cmp(tv, &e->mainloop->cached_next_time_event->timeval) < 0)
+        if (t < e->mainloop->cached_next_time_event->time)
             e->mainloop->cached_next_time_event = e;
     } else if (e->mainloop->cached_next_time_event == e)
         e->mainloop->cached_next_time_event = NULL;
             e->mainloop->cached_next_time_event = e;
     } else if (e->mainloop->cached_next_time_event == e)
         e->mainloop->cached_next_time_event = NULL;
@@ -387,13 +419,13 @@ static void mainloop_time_free(pa_time_event *e) {
     pa_assert(e);
     pa_assert(!e->dead);
 
     pa_assert(e);
     pa_assert(!e->dead);
 
-    e->dead = 1;
+    e->dead = TRUE;
     e->mainloop->time_events_please_scan ++;
 
     if (e->enabled) {
         pa_assert(e->mainloop->n_enabled_time_events > 0);
         e->mainloop->n_enabled_time_events--;
     e->mainloop->time_events_please_scan ++;
 
     if (e->enabled) {
         pa_assert(e->mainloop->n_enabled_time_events > 0);
         e->mainloop->n_enabled_time_events--;
-        e->enabled = 0;
+        e->enabled = FALSE;
     }
 
     if (e->mainloop->cached_next_time_event == e)
     }
 
     if (e->mainloop->cached_next_time_event == e)
@@ -425,10 +457,10 @@ static void mainloop_quit(pa_mainloop_api*a, int retval) {
 static const pa_mainloop_api vtable = {
     .userdata = NULL,
 
 static const pa_mainloop_api vtable = {
     .userdata = NULL,
 
-    .io_new= mainloop_io_new,
-    .io_enable= mainloop_io_enable,
-    .io_free= mainloop_io_free,
-    .io_set_destroy= mainloop_io_set_destroy,
+    .io_new = mainloop_io_new,
+    .io_enable = mainloop_io_enable,
+    .io_free = mainloop_io_free,
+    .io_set_destroy = mainloop_io_set_destroy,
 
     .time_new = mainloop_time_new,
     .time_restart = mainloop_time_restart,
 
     .time_new = mainloop_time_new,
     .time_restart = mainloop_time_restart,
@@ -446,6 +478,8 @@ static const pa_mainloop_api vtable = {
 pa_mainloop *pa_mainloop_new(void) {
     pa_mainloop *m;
 
 pa_mainloop *pa_mainloop_new(void) {
     pa_mainloop *m;
 
+    pa_init_i18n();
+
     m = pa_xnew(pa_mainloop, 1);
 
     m->wakeup_pipe_type = 0;
     m = pa_xnew(pa_mainloop, 1);
 
     m->wakeup_pipe_type = 0;
@@ -459,7 +493,7 @@ pa_mainloop *pa_mainloop_new(void) {
     pa_make_fd_nonblock(m->wakeup_pipe[1]);
     pa_make_fd_cloexec(m->wakeup_pipe[0]);
     pa_make_fd_cloexec(m->wakeup_pipe[1]);
     pa_make_fd_nonblock(m->wakeup_pipe[1]);
     pa_make_fd_cloexec(m->wakeup_pipe[0]);
     pa_make_fd_cloexec(m->wakeup_pipe[1]);
-    m->wakeup_requested = 0;
+    m->wakeup_requested = FALSE;
 
     PA_LLIST_HEAD_INIT(pa_io_event, m->io_events);
     PA_LLIST_HEAD_INIT(pa_time_event, m->time_events);
 
     PA_LLIST_HEAD_INIT(pa_io_event, m->io_events);
     PA_LLIST_HEAD_INIT(pa_time_event, m->time_events);
@@ -473,9 +507,10 @@ pa_mainloop *pa_mainloop_new(void) {
 
     m->pollfds = NULL;
     m->max_pollfds = m->n_pollfds = 0;
 
     m->pollfds = NULL;
     m->max_pollfds = m->n_pollfds = 0;
-    m->rebuild_pollfds = 1;
+    m->rebuild_pollfds = TRUE;
 
 
-    m->quit = m->retval = 0;
+    m->quit = FALSE;
+    m->retval = 0;
 
     m->api = vtable;
     m->api.userdata = m;
 
     m->api = vtable;
     m->api.userdata = m;
@@ -489,7 +524,7 @@ pa_mainloop *pa_mainloop_new(void) {
     return m;
 }
 
     return m;
 }
 
-static void cleanup_io_events(pa_mainloop *m, int force) {
+static void cleanup_io_events(pa_mainloop *m, pa_bool_t force) {
     pa_io_event *e;
 
     e = m->io_events;
     pa_io_event *e;
 
     e = m->io_events;
@@ -512,7 +547,7 @@ static void cleanup_io_events(pa_mainloop *m, int force) {
 
             pa_xfree(e);
 
 
             pa_xfree(e);
 
-            m->rebuild_pollfds = 1;
+            m->rebuild_pollfds = TRUE;
         }
 
         e = n;
         }
 
         e = n;
@@ -521,7 +556,7 @@ static void cleanup_io_events(pa_mainloop *m, int force) {
     pa_assert(m->io_events_please_scan == 0);
 }
 
     pa_assert(m->io_events_please_scan == 0);
 }
 
-static void cleanup_time_events(pa_mainloop *m, int force) {
+static void cleanup_time_events(pa_mainloop *m, pa_bool_t force) {
     pa_time_event *e;
 
     e = m->time_events;
     pa_time_event *e;
 
     e = m->time_events;
@@ -542,7 +577,7 @@ static void cleanup_time_events(pa_mainloop *m, int force) {
             if (!e->dead && e->enabled) {
                 pa_assert(m->n_enabled_time_events > 0);
                 m->n_enabled_time_events--;
             if (!e->dead && e->enabled) {
                 pa_assert(m->n_enabled_time_events > 0);
                 m->n_enabled_time_events--;
-                e->enabled = 0;
+                e->enabled = FALSE;
             }
 
             if (e->destroy_callback)
             }
 
             if (e->destroy_callback)
@@ -557,7 +592,7 @@ static void cleanup_time_events(pa_mainloop *m, int force) {
     pa_assert(m->time_events_please_scan == 0);
 }
 
     pa_assert(m->time_events_please_scan == 0);
 }
 
-static void cleanup_defer_events(pa_mainloop *m, int force) {
+static void cleanup_defer_events(pa_mainloop *m, pa_bool_t force) {
     pa_defer_event *e;
 
     e = m->defer_events;
     pa_defer_event *e;
 
     e = m->defer_events;
@@ -578,7 +613,7 @@ static void cleanup_defer_events(pa_mainloop *m, int force) {
             if (!e->dead && e->enabled) {
                 pa_assert(m->n_enabled_defer_events > 0);
                 m->n_enabled_defer_events--;
             if (!e->dead && e->enabled) {
                 pa_assert(m->n_enabled_defer_events > 0);
                 m->n_enabled_defer_events--;
-                e->enabled = 0;
+                e->enabled = FALSE;
             }
 
             if (e->destroy_callback)
             }
 
             if (e->destroy_callback)
@@ -597,9 +632,9 @@ static void cleanup_defer_events(pa_mainloop *m, int force) {
 void pa_mainloop_free(pa_mainloop* m) {
     pa_assert(m);
 
 void pa_mainloop_free(pa_mainloop* m) {
     pa_assert(m);
 
-    cleanup_io_events(m, 1);
-    cleanup_defer_events(m, 1);
-    cleanup_time_events(m, 1);
+    cleanup_io_events(m, TRUE);
+    cleanup_defer_events(m, TRUE);
+    cleanup_time_events(m, TRUE);
 
     pa_xfree(m->pollfds);
 
 
     pa_xfree(m->pollfds);
 
@@ -612,13 +647,13 @@ static void scan_dead(pa_mainloop *m) {
     pa_assert(m);
 
     if (m->io_events_please_scan)
     pa_assert(m);
 
     if (m->io_events_please_scan)
-        cleanup_io_events(m, 0);
+        cleanup_io_events(m, FALSE);
 
     if (m->time_events_please_scan)
 
     if (m->time_events_please_scan)
-        cleanup_time_events(m, 0);
+        cleanup_time_events(m, FALSE);
 
     if (m->defer_events_please_scan)
 
     if (m->defer_events_please_scan)
-        cleanup_defer_events(m, 0);
+        cleanup_defer_events(m, FALSE);
 }
 
 static void rebuild_pollfds(pa_mainloop *m) {
 }
 
 static void rebuild_pollfds(pa_mainloop *m) {
@@ -659,7 +694,7 @@ static void rebuild_pollfds(pa_mainloop *m) {
         m->n_pollfds++;
     }
 
         m->n_pollfds++;
     }
 
-    m->rebuild_pollfds = 0;
+    m->rebuild_pollfds = FALSE;
 }
 
 static int dispatch_pollfds(pa_mainloop *m) {
 }
 
 static int dispatch_pollfds(pa_mainloop *m) {
@@ -715,11 +750,11 @@ static pa_time_event* find_next_time_event(pa_mainloop *m) {
         if (t->dead || !t->enabled)
             continue;
 
         if (t->dead || !t->enabled)
             continue;
 
-        if (!n || pa_timeval_cmp(&t->timeval, &n->timeval) < 0) {
+        if (!n || t->time < n->time) {
             n = t;
 
             n = t;
 
-            /* Shortcut for tv = { 0, 0 } */
-            if (n->timeval.tv_sec <= 0)
+            /* Shortcut for time == 0 */
+            if (n->time == 0)
                 break;
         }
     }
                 break;
         }
     }
@@ -730,50 +765,48 @@ static pa_time_event* find_next_time_event(pa_mainloop *m) {
 
 static int calc_next_timeout(pa_mainloop *m) {
     pa_time_event *t;
 
 static int calc_next_timeout(pa_mainloop *m) {
     pa_time_event *t;
-    struct timeval now;
-    pa_usec_t usec;
+    pa_usec_t clock_now;
 
     if (!m->n_enabled_time_events)
         return -1;
 
 
     if (!m->n_enabled_time_events)
         return -1;
 
-    t = find_next_time_event(m);
-    pa_assert(t);
+    pa_assert_se(t = find_next_time_event(m));
 
 
-    if (t->timeval.tv_sec <= 0)
+    if (t->time <= 0)
         return 0;
 
         return 0;
 
-    pa_gettimeofday(&now);
+    clock_now = pa_rtclock_now();
 
 
-    if (pa_timeval_cmp(&t->timeval, &now) <= 0)
+    if (t->time <= clock_now)
         return 0;
 
         return 0;
 
-    usec = pa_timeval_diff(&t->timeval, &now);
-    return (int) (usec / 1000);
+    return (int) ((t->time - clock_now) / 1000); /* in milliseconds */
 }
 
 static int dispatch_timeout(pa_mainloop *m) {
     pa_time_event *e;
 }
 
 static int dispatch_timeout(pa_mainloop *m) {
     pa_time_event *e;
-    struct timeval now;
+    pa_usec_t now;
     int r = 0;
     pa_assert(m);
 
     if (m->n_enabled_time_events <= 0)
         return 0;
 
     int r = 0;
     pa_assert(m);
 
     if (m->n_enabled_time_events <= 0)
         return 0;
 
-    pa_gettimeofday(&now);
+    now = pa_rtclock_now();
 
     for (e = m->time_events; e && !m->quit; e = e->next) {
 
         if (e->dead || !e->enabled)
             continue;
 
 
     for (e = m->time_events; e && !m->quit; e = e->next) {
 
         if (e->dead || !e->enabled)
             continue;
 
-        if (pa_timeval_cmp(&e->timeval, &now) <= 0) {
+        if (e->time <= now) {
+            struct timeval tv;
             pa_assert(e->callback);
 
             /* Disable time event */
             mainloop_time_restart(e, NULL);
 
             pa_assert(e->callback);
 
             /* Disable time event */
             mainloop_time_restart(e, NULL);
 
-            e->callback(&m->api, e, &e->timeval, e->userdata);
+            e->callback(&m->api, e, pa_timeval_rtstore(&tv, e->time, TRUE), e->userdata);
 
             r++;
         }
 
             r++;
         }
@@ -945,7 +978,7 @@ int pa_mainloop_run(pa_mainloop *m, int *retval) {
 void pa_mainloop_quit(pa_mainloop *m, int retval) {
     pa_assert(m);
 
 void pa_mainloop_quit(pa_mainloop *m, int retval) {
     pa_assert(m);
 
-    m->quit = 1;
+    m->quit = TRUE;
     m->retval = retval;
     pa_mainloop_wakeup(m);
 }
     m->retval = retval;
     pa_mainloop_wakeup(m);
 }
@@ -961,3 +994,9 @@ void pa_mainloop_set_poll_func(pa_mainloop *m, pa_poll_func poll_func, void *use
     m->poll_func = poll_func;
     m->poll_func_userdata = userdata;
 }
     m->poll_func = poll_func;
     m->poll_func_userdata = userdata;
 }
+
+pa_bool_t pa_mainloop_is_our_api(pa_mainloop_api*m) {
+    pa_assert(m);
+
+    return m->io_new == mainloop_io_new;
+}