]> code.delx.au - pulseaudio/blobdiff - src/pulse/glib-mainloop.c
channelmap, volume: Don't refer to bool in the public API documentation
[pulseaudio] / src / pulse / glib-mainloop.c
index 77f934501ef90e445304e4bb1272083961da726f..bd24913b465cff0069ccf362fd897ac32e0a5c63 100644 (file)
@@ -1,18 +1,18 @@
-/* $Id$ */
-
 /***
   This file is part of PulseAudio.
+
+  Copyright 2004-2006 Lennart Poettering
+
   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
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   General Public License for more details.
+
   You should have received a copy of the GNU Lesser General Public License
   along with PulseAudio; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 #include <config.h>
 #endif
 
-#include <assert.h>
-
 #include <pulse/xmalloc.h>
 #include <pulse/timeval.h>
 
-#include <pulsecore/idxset.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/log.h>
 #include <pulsecore/llist.h>
@@ -36,7 +33,7 @@
 #include <glib.h>
 #include "glib-mainloop.h"
 
-struct pa_io_event  {
+struct pa_io_event {
     pa_glib_mainloop *mainloop;
     int dead;
 
@@ -69,7 +66,7 @@ struct pa_defer_event {
     int dead;
 
     int enabled;
-    
+
     pa_defer_event_cb_t callback;
     void *userdata;
     pa_defer_event_destroy_cb_t destroy_callback;
@@ -79,7 +76,7 @@ struct pa_defer_event {
 
 struct pa_glib_mainloop {
     GSource source;
-    
+
     pa_mainloop_api api;
     GMainContext *context;
 
@@ -102,26 +99,28 @@ static void cleanup_io_events(pa_glib_mainloop *g, int force) {
 
         if (!force && g->io_events_please_scan <= 0)
             break;
-        
+
         if (force || e->dead) {
             PA_LLIST_REMOVE(pa_io_event, g->io_events, e);
 
-            if (e->dead)
+            if (e->dead) {
+                g_assert(g->io_events_please_scan > 0);
                 g->io_events_please_scan--;
-            
+            }
+
             if (e->poll_fd_added)
                 g_source_remove_poll(&g->source, &e->poll_fd);
-            
+
             if (e->destroy_callback)
                 e->destroy_callback(&g->api, e, e->userdata);
-            
+
             pa_xfree(e);
         }
 
         e = n;
     }
 
-    assert(g->io_events_please_scan == 0);
+    g_assert(g->io_events_please_scan == 0);
 }
 
 static void cleanup_time_events(pa_glib_mainloop *g, int force) {
@@ -133,26 +132,30 @@ static void cleanup_time_events(pa_glib_mainloop *g, int force) {
 
         if (!force && g->time_events_please_scan <= 0)
             break;
-        
+
         if (force || e->dead) {
             PA_LLIST_REMOVE(pa_time_event, g->time_events, e);
 
-            if (e->dead)
+            if (e->dead) {
+                g_assert(g->time_events_please_scan > 0);
                 g->time_events_please_scan--;
+            }
 
-            if (!e->dead && e->enabled)
+            if (!e->dead && e->enabled) {
+                g_assert(g->n_enabled_time_events > 0);
                 g->n_enabled_time_events--;
-            
+            }
+
             if (e->destroy_callback)
                 e->destroy_callback(&g->api, e, e->userdata);
-            
+
             pa_xfree(e);
         }
 
         e = n;
     }
 
-    assert(g->time_events_please_scan == 0);
+    g_assert(g->time_events_please_scan == 0);
 }
 
 static void cleanup_defer_events(pa_glib_mainloop *g, int force) {
@@ -164,34 +167,38 @@ static void cleanup_defer_events(pa_glib_mainloop *g, int force) {
 
         if (!force && g->defer_events_please_scan <= 0)
             break;
-        
+
         if (force || e->dead) {
             PA_LLIST_REMOVE(pa_defer_event, g->defer_events, e);
 
-            if (e->dead)
+            if (e->dead) {
+                g_assert(g->defer_events_please_scan > 0);
                 g->defer_events_please_scan--;
+            }
 
-            if (!e->dead && e->enabled)
+            if (!e->dead && e->enabled) {
+                g_assert(g->n_enabled_defer_events > 0);
                 g->n_enabled_defer_events--;
-            
+            }
+
             if (e->destroy_callback)
                 e->destroy_callback(&g->api, e, e->userdata);
-            
+
             pa_xfree(e);
         }
 
         e = n;
     }
 
-    assert(g->defer_events_please_scan == 0);
+    g_assert(g->defer_events_please_scan == 0);
 }
 
 static gushort map_flags_to_glib(pa_io_event_flags_t flags) {
-    return
-        (flags & PA_IO_EVENT_INPUT ? G_IO_IN : 0) |
-        (flags & PA_IO_EVENT_OUTPUT ? G_IO_OUT : 0) |
-        (flags & PA_IO_EVENT_ERROR ? G_IO_ERR : 0) |
-        (flags & PA_IO_EVENT_HANGUP ? G_IO_HUP : 0);
+    return (gushort)
+        ((flags & PA_IO_EVENT_INPUT ? G_IO_IN : 0) |
+         (flags & PA_IO_EVENT_OUTPUT ? G_IO_OUT : 0) |
+         (flags & PA_IO_EVENT_ERROR ? G_IO_ERR : 0) |
+         (flags & PA_IO_EVENT_HANGUP ? G_IO_HUP : 0));
 }
 
 static pa_io_event_flags_t map_flags_from_glib(gushort flags) {
@@ -208,15 +215,15 @@ static pa_io_event* glib_io_new(
         pa_io_event_flags_t f,
         pa_io_event_cb_t cb,
         void *userdata) {
-    
+
     pa_io_event *e;
     pa_glib_mainloop *g;
 
-    assert(m);
-    assert(m->userdata);
-    assert(fd >= 0);
-    assert(cb);
-    
+    g_assert(m);
+    g_assert(m->userdata);
+    g_assert(fd >= 0);
+    g_assert(cb);
+
     g = m->userdata;
 
     e = pa_xnew(pa_io_event, 1);
@@ -226,7 +233,7 @@ static pa_io_event* glib_io_new(
     e->poll_fd.fd = fd;
     e->poll_fd.events = map_flags_to_glib(f);
     e->poll_fd.revents = 0;
-    
+
     e->callback = cb;
     e->userdata = userdata;
     e->destroy_callback = NULL;
@@ -235,20 +242,20 @@ static pa_io_event* glib_io_new(
 
     g_source_add_poll(&g->source, &e->poll_fd);
     e->poll_fd_added = 1;
-    
+
     return e;
 }
 
 static void glib_io_enable(pa_io_event*e, pa_io_event_flags_t f) {
-    assert(e);
-    assert(!e->dead);
+    g_assert(e);
+    g_assert(!e->dead);
 
     e->poll_fd.events = map_flags_to_glib(f);
 }
 
 static void glib_io_free(pa_io_event*e) {
-    assert(e);
-    assert(!e->dead);
+    g_assert(e);
+    g_assert(!e->dead);
 
     e->dead = 1;
     e->mainloop->io_events_please_scan++;
@@ -260,9 +267,9 @@ static void glib_io_free(pa_io_event*e) {
 }
 
 static void glib_io_set_destroy(pa_io_event*e, pa_io_event_destroy_cb_t cb) {
-    assert(e);
-    assert(!e->dead);
-    
+    g_assert(e);
+    g_assert(!e->dead);
+
     e->destroy_callback = cb;
 }
 
@@ -273,14 +280,14 @@ static pa_time_event* glib_time_new(
         const struct timeval *tv,
         pa_time_event_cb_t cb,
         void *userdata) {
-    
+
     pa_glib_mainloop *g;
     pa_time_event *e;
-    
-    assert(m);
-    assert(m->userdata);
-    assert(cb);
-    
+
+    g_assert(m);
+    g_assert(m->userdata);
+    g_assert(cb);
+
     g = m->userdata;
 
     e = pa_xnew(pa_time_event, 1);
@@ -298,23 +305,24 @@ static pa_time_event* glib_time_new(
                 g->cached_next_time_event = e;
         }
     }
-    
+
     e->callback = cb;
     e->userdata = userdata;
     e->destroy_callback = NULL;
 
     PA_LLIST_PREPEND(pa_time_event, g->time_events, e);
-    
+
     return e;
 }
 
 static void glib_time_restart(pa_time_event*e, const struct timeval *tv) {
-    assert(e);
-    assert(!e->dead);
+    g_assert(e);
+    g_assert(!e->dead);
 
-    if (e->enabled && !tv)
+    if (e->enabled && !tv) {
+        g_assert(e->mainloop->n_enabled_time_events > 0);
         e->mainloop->n_enabled_time_events--;
-    else if (!e->enabled && tv)
+    else if (!e->enabled && tv)
         e->mainloop->n_enabled_time_events++;
 
     if ((e->enabled = !!tv))
@@ -327,11 +335,11 @@ static void glib_time_restart(pa_time_event*e, const struct timeval *tv) {
             e->mainloop->cached_next_time_event = e;
     } else if (e->mainloop->cached_next_time_event == e)
         e->mainloop->cached_next_time_event = NULL;
- }
+}
 
 static void glib_time_free(pa_time_event *e) {
-    assert(e);
-    assert(!e->dead);
+    g_assert(e);
+    g_assert(!e->dead);
 
     e->dead = 1;
     e->mainloop->time_events_please_scan++;
@@ -344,9 +352,9 @@ static void glib_time_free(pa_time_event *e) {
 }
 
 static void glib_time_set_destroy(pa_time_event *e, pa_time_event_destroy_cb_t cb) {
-    assert(e);
-    assert(!e->dead);
-    
+    g_assert(e);
+    g_assert(!e->dead);
+
     e->destroy_callback = cb;
 }
 
@@ -356,77 +364,80 @@ static pa_defer_event* glib_defer_new(
         pa_mainloop_api*m,
         pa_defer_event_cb_t cb,
         void *userdata) {
-    
+
     pa_defer_event *e;
     pa_glib_mainloop *g;
 
-    assert(m);
-    assert(m->userdata);
-    assert(cb);
-    
+    g_assert(m);
+    g_assert(m->userdata);
+    g_assert(cb);
+
     g = m->userdata;
-    
+
     e = pa_xnew(pa_defer_event, 1);
     e->mainloop = g;
     e->dead = 0;
 
     e->enabled = 1;
     g->n_enabled_defer_events++;
-    
+
     e->callback = cb;
     e->userdata = userdata;
     e->destroy_callback = NULL;
-    
+
     PA_LLIST_PREPEND(pa_defer_event, g->defer_events, e);
     return e;
 }
 
 static void glib_defer_enable(pa_defer_event *e, int b) {
-    assert(e);
-    assert(!e->dead);
+    g_assert(e);
+    g_assert(!e->dead);
 
-    if (e->enabled && !b)
+    if (e->enabled && !b) {
+        g_assert(e->mainloop->n_enabled_defer_events > 0);
         e->mainloop->n_enabled_defer_events--;
-    else if (!e->enabled && b)
+    else if (!e->enabled && b)
         e->mainloop->n_enabled_defer_events++;
 
     e->enabled = b;
 }
 
 static void glib_defer_free(pa_defer_event *e) {
-    assert(e);
-    assert(!e->dead);
+    g_assert(e);
+    g_assert(!e->dead);
 
     e->dead = 1;
     e->mainloop->defer_events_please_scan++;
 
-    if (e->enabled)
+    if (e->enabled) {
+        g_assert(e->mainloop->n_enabled_defer_events > 0);
         e->mainloop->n_enabled_defer_events--;
+    }
 }
 
 static void glib_defer_set_destroy(pa_defer_event *e, pa_defer_event_destroy_cb_t cb) {
-    assert(e);
-    assert(!e->dead);
+    g_assert(e);
+    g_assert(!e->dead);
 
     e->destroy_callback = cb;
 }
 
 /* quit() */
 
-static void glib_quit(pa_mainloop_api*a, PA_GCC_UNUSED int retval) {
+static void glib_quit(pa_mainloop_api*a, int retval) {
 
     g_warning("quit() ignored");
-    
+
     /* NOOP */
 }
 
 static pa_time_event* find_next_time_event(pa_glib_mainloop *g) {
     pa_time_event *t, *n = NULL;
-    assert(g);
+    g_assert(g);
 
     if (g->cached_next_time_event)
         return g->cached_next_time_event;
-    
+
     for (t = g->time_events; t; t = t->next) {
 
         if (t->dead || !t->enabled)
@@ -445,11 +456,8 @@ static pa_time_event* find_next_time_event(pa_glib_mainloop *g) {
     return n;
 }
 
-static gboolean prepare_func(GSource *source, gint *timeout) {
-    pa_glib_mainloop *g = (pa_glib_mainloop*) source;
-
+static void scan_dead(pa_glib_mainloop *g) {
     g_assert(g);
-    g_assert(timeout);
 
     if (g->io_events_please_scan)
         cleanup_io_events(g, 0);
@@ -459,6 +467,15 @@ static gboolean prepare_func(GSource *source, gint *timeout) {
 
     if (g->defer_events_please_scan)
         cleanup_defer_events(g, 0);
+}
+
+static gboolean prepare_func(GSource *source, gint *timeout) {
+    pa_glib_mainloop *g = (pa_glib_mainloop*) source;
+
+    g_assert(g);
+    g_assert(timeout);
+
+    scan_dead(g);
 
     if (g->n_enabled_defer_events) {
         *timeout = 0;
@@ -472,14 +489,14 @@ static gboolean prepare_func(GSource *source, gint *timeout) {
         t = find_next_time_event(g);
         g_assert(t);
 
-        g_source_get_current_time(source, &now);
+        g_get_current_time(&now);
         tvnow.tv_sec = now.tv_sec;
         tvnow.tv_usec = now.tv_usec;
 
         if (pa_timeval_cmp(&t->timeval, &tvnow) <= 0) {
             *timeout = 0;
             return TRUE;
-        } 
+        }
         usec = pa_timeval_diff(&t->timeval, &tvnow);
         *timeout = (gint) (usec / 1000);
     } else
@@ -499,11 +516,11 @@ static gboolean check_func(GSource *source) {
         pa_time_event *t;
         GTimeVal now;
         struct timeval tvnow;
-    
+
         t = find_next_time_event(g);
         g_assert(t);
-        
-        g_source_get_current_time(source, &now);
+
+        g_get_current_time(&now);
         tvnow.tv_sec = now.tv_sec;
         tvnow.tv_usec = now.tv_usec;
 
@@ -518,7 +535,7 @@ static gboolean check_func(GSource *source) {
     return FALSE;
 }
 
-static gboolean dispatch_func(GSource *source, PA_GCC_UNUSED GSourceFunc callback, PA_GCC_UNUSED gpointer userdata) {
+static gboolean dispatch_func(GSource *source, GSourceFunc callback, gpointer userdata) {
     pa_glib_mainloop *g = (pa_glib_mainloop*) source;
     pa_io_event *e;
 
@@ -534,8 +551,8 @@ static gboolean dispatch_func(GSource *source, PA_GCC_UNUSED GSourceFunc callbac
             break;
         }
 
-        assert(d);
-        
+        g_assert(d);
+
         d->callback(&g->api, d, d->userdata);
         return TRUE;
     }
@@ -547,12 +564,16 @@ static gboolean dispatch_func(GSource *source, PA_GCC_UNUSED GSourceFunc callbac
 
         t = find_next_time_event(g);
         g_assert(t);
-        
-        g_source_get_current_time(source, &now);
+
+        g_get_current_time(&now);
         tvnow.tv_sec = now.tv_sec;
         tvnow.tv_usec = now.tv_usec;
 
         if (pa_timeval_cmp(&t->timeval, &tvnow) <= 0) {
+
+            /* Disable time event */
+            glib_time_restart(t, NULL);
+
             t->callback(&g->api, t, &t->timeval, t->userdata);
             return TRUE;
         }
@@ -580,12 +601,12 @@ static const pa_mainloop_api vtable = {
     .time_restart = glib_time_restart,
     .time_free = glib_time_free,
     .time_set_destroy = glib_time_set_destroy,
-    
+
     .defer_new = glib_defer_new,
     .defer_enable = glib_defer_enable,
     .defer_free = glib_defer_free,
     .defer_set_destroy = glib_defer_set_destroy,
-    
+
     .quit = glib_quit,
 };
 
@@ -600,10 +621,10 @@ pa_glib_mainloop *pa_glib_mainloop_new(GMainContext *c) {
         NULL,
         NULL
     };
-    
+
     g = (pa_glib_mainloop*) g_source_new(&source_funcs, sizeof(pa_glib_mainloop));
     g_main_context_ref(g->context = c ? c : g_main_context_default());
-    
+
     g->api = vtable;
     g->api.userdata = g;
 
@@ -613,15 +634,17 @@ pa_glib_mainloop *pa_glib_mainloop_new(GMainContext *c) {
 
     g->n_enabled_defer_events = g->n_enabled_time_events = 0;
     g->io_events_please_scan = g->time_events_please_scan = g->defer_events_please_scan = 0;
-    
+
+    g->cached_next_time_event = NULL;
+
     g_source_attach(&g->source, g->context);
     g_source_set_can_recurse(&g->source, FALSE);
-    
+
     return g;
 }
 
 void pa_glib_mainloop_free(pa_glib_mainloop* g) {
-    assert(g);
+    g_assert(g);
 
     cleanup_io_events(g, 1);
     cleanup_defer_events(g, 1);
@@ -633,7 +656,7 @@ void pa_glib_mainloop_free(pa_glib_mainloop* g) {
 }
 
 pa_mainloop_api* pa_glib_mainloop_get_api(pa_glib_mainloop *g) {
-    assert(g);
-    
+    g_assert(g);
+
     return &g->api;
 }