add new function pa_mainloop_deferred_pending()
authorLennart Poettering <lennart@poettering.net>
Sun, 19 Sep 2004 00:03:12 +0000 (00:03 +0000)
committerLennart Poettering <lennart@poettering.net>
Sun, 19 Sep 2004 00:03:12 +0000 (00:03 +0000)
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@221 fefdeb5f-60dc-0310-8127-8f9354f1896f

doc/todo
polyp/Makefile.am
polyp/mainloop.c
polyp/mainloop.h
polyp/polyplib-simple.c

index adf305c..22d59e6 100644 (file)
--- a/doc/todo
+++ b/doc/todo
@@ -12,7 +12,6 @@
 - make mcalign merge chunks
 - option to use default fragment size on alsa drivers
 - improve module-oss-mmap latency measurement
-- new mainloop method: defer_pending()
 
 ** later ***
 - xmlrpc/http
index e757444..4adc8ad 100644 (file)
@@ -334,7 +334,7 @@ libpolyp_@PA_MAJORMINOR@_la_SOURCES = polyplib.h \
                llist.h \
                log.c log.h \
                gcc-printf.h \
-               client-conf.c client-conf.h \
+               client-conf.c client-conf.h \
                conf-parser.c conf-parser.h
 
 libpolyp_@PA_MAJORMINOR@_la_CFLAGS = $(AM_CFLAGS)
@@ -366,11 +366,11 @@ pactl_LDADD = $(AM_LDADD) libpolyp-@PA_MAJORMINOR@.la libpolyp-error-@PA_MAJORMI
 pactl_CFLAGS = $(AM_CFLAGS) $(LIBSDNFILE_CFLAGS)
 
 pacat_simple_SOURCES = pacat-simple.c
-pacat_simple_LDADD = $(AM_LDADD) libpolyp-@PA_MAJORMINOR@.la libpolyp-simple-@PA_MAJORMINOR@.la libpolyp-error-@PA_MAJORMINOR@.la
+pacat_simple_LDADD = $(AM_LDADD) libpolyp-@PA_MAJORMINOR@.la libpolyp-simple-@PA_MAJORMINOR@.la libpolyp-error-@PA_MAJORMINOR@.la libpolyp-mainloop-@PA_MAJORMINOR@.la
 pacat_simple_CFLAGS = $(AM_CFLAGS)
 
 parec_simple_SOURCES = parec-simple.c
-parec_simple_LDADD = $(AM_LDADD) libpolyp-@PA_MAJORMINOR@.la libpolyp-simple-@PA_MAJORMINOR@.la libpolyp-error-@PA_MAJORMINOR@.la
+parec_simple_LDADD = $(AM_LDADD) libpolyp-@PA_MAJORMINOR@.la libpolyp-simple-@PA_MAJORMINOR@.la libpolyp-error-@PA_MAJORMINOR@.la libpolyp-mainloop-@PA_MAJORMINOR@.la
 parec_simple_CFLAGS = $(AM_CFLAGS)
 
 mainloop_test_SOURCES = mainloop-test.c
@@ -541,7 +541,7 @@ esdcompat.sh: esdcompat.sh.in Makefile
        sed -e 's,@PACKAGE_VERSION\@,$(PACKAGE_VERSION),g' \
                -e 's,@PACKAGE_NAME\@,$(PACKAGE_NAME),g' \
                -e 's,@POLYPAUDIO_BINARY\@,$(bindir)/polypaudio,g' < $< > $@
-               
+
 client.conf: client.conf.in Makefile
        sed -e 's,@POLYPAUDIO_BINARY\@,$(bindir)/polypaudio,g' < $< > $@
 
index c4e12ac..80bcb12 100644 (file)
@@ -79,6 +79,8 @@ struct pa_mainloop {
 
     int quit, running, retval;
     struct pa_mainloop_api api;
+
+    int deferred_pending;
 };
 
 /* IO events */
@@ -147,17 +149,32 @@ struct pa_defer_event* mainloop_defer_new(struct pa_mainloop_api*a, void (*callb
     e->destroy_callback = NULL;
 
     pa_idxset_put(m->defer_events, e, NULL);
+
+    m->deferred_pending++;
     return e;
 }
 
 static void mainloop_defer_enable(struct pa_defer_event *e, int b) {
     assert(e);
+
+    if (e->enabled && !b) {
+        assert(e->mainloop->deferred_pending > 0);
+        e->mainloop->deferred_pending--;
+    } else if (!e->enabled && b)
+        e->mainloop->deferred_pending++;
+    
     e->enabled = b;
 }
 
 static void mainloop_defer_free(struct pa_defer_event *e) {
     assert(e);
     e->dead = e->mainloop->defer_events_scan_dead = 1;
+
+    if (e->enabled) {
+        e->enabled = 0;
+        assert(e->mainloop->deferred_pending > 0);
+        e->mainloop->deferred_pending--;
+    }
 }
 
 static void mainloop_defer_set_destroy(struct pa_defer_event *e, void (*callback)(struct pa_mainloop_api*a, struct pa_defer_event *e, void *userdata)) {
@@ -265,6 +282,8 @@ struct pa_mainloop *pa_mainloop_new(void) {
 
     m->api = vtable;
     m->api.userdata = m;
+
+    m->deferred_pending = 0;
     
     return m;
 }
@@ -383,7 +402,7 @@ static int dispatch_pollfds(struct pa_mainloop *m) {
     struct pa_io_event *e;
     int r = 0;
 
-    for (e = pa_idxset_first(m->io_events, &index); e; e = pa_idxset_next(m->io_events, &index)) {
+    for (e = pa_idxset_first(m->io_events, &index); e && !m->quit; e = pa_idxset_next(m->io_events, &index)) {
         if (e->dead || !e->pollfd || !e->pollfd->revents)
             continue;
         
@@ -406,7 +425,7 @@ static int dispatch_defer(struct pa_mainloop *m) {
     struct pa_defer_event *e;
     int r = 0;
 
-    for (e = pa_idxset_first(m->defer_events, &index); e; e = pa_idxset_next(m->defer_events, &index)) {
+    for (e = pa_idxset_first(m->defer_events, &index); e && !m->quit; e = pa_idxset_next(m->defer_events, &index)) {
         if (e->dead || !e->enabled)
             continue;
  
@@ -470,7 +489,7 @@ static int dispatch_timeout(struct pa_mainloop *m) {
     if (pa_idxset_isempty(m->time_events))
         return 0;
 
-    for (e = pa_idxset_first(m->time_events, &index); e; e = pa_idxset_next(m->time_events, &index)) {
+    for (e = pa_idxset_first(m->time_events, &index); e && !m->quit; e = pa_idxset_next(m->time_events, &index)) {
         
         if (e->dead || !e->enabled)
             continue;
@@ -498,17 +517,17 @@ int pa_mainloop_iterate(struct pa_mainloop *m, int block, int *retval) {
     int r, t, dispatched = 0;
     assert(m && !m->running);
     
-    if(m->quit) {
-        if (retval)
-            *retval = m->retval;
-        return -2;
-    }
-
     m->running = 1;
 
+    if(m->quit)
+        goto quit;
+
     scan_dead(m);
     dispatched += dispatch_defer(m);
 
+    if(m->quit)
+        goto quit;
+    
     if (m->rebuild_pollfds) {
         rebuild_pollfds(m);
         m->rebuild_pollfds = 0;
@@ -524,9 +543,16 @@ int pa_mainloop_iterate(struct pa_mainloop *m, int block, int *retval) {
             pa_log(__FILE__": select(): %s\n", strerror(errno));
     } else {
         dispatched += dispatch_timeout(m);
+
+        if(m->quit)
+            goto quit;
         
-        if (r > 0)
+        if (r > 0) {
             dispatched += dispatch_pollfds(m);
+
+            if(m->quit)
+                goto quit;
+        }
     }
     
     m->running = 0;
@@ -534,6 +560,15 @@ int pa_mainloop_iterate(struct pa_mainloop *m, int block, int *retval) {
 /*     pa_log("dispatched: %i\n", dispatched); */
     
     return r < 0 ? -1 : dispatched;
+
+quit:
+
+    m->running = 0;
+    
+    if (retval) 
+        *retval = m->retval;
+    
+    return -2;
 }
 
 int pa_mainloop_run(struct pa_mainloop *m, int *retval) {
@@ -557,3 +592,8 @@ struct pa_mainloop_api* pa_mainloop_get_api(struct pa_mainloop*m) {
     assert(m);
     return &m->api;
 }
+
+int pa_mainloop_deferred_pending(struct pa_mainloop *m) {
+    assert(m);
+    return m->deferred_pending > 0;
+}
index a0fe126..4a64d98 100644 (file)
@@ -59,6 +59,9 @@ int pa_mainloop_run(struct pa_mainloop *m, int *retval);
 /** Return the abstract main loop abstraction layer vtable for this main loop. This calls pa_mainloop_iterate() iteratively.*/
 struct pa_mainloop_api* pa_mainloop_get_api(struct pa_mainloop*m);
 
+/** Return non-zero when there are any deferred events pending. \since 0.5 */
+int pa_mainloop_deferred_pending(struct pa_mainloop *m);
+
 PA_C_DECL_END
 
 #endif
index 5cf52d0..aa6c88f 100644 (file)
@@ -99,6 +99,19 @@ static int iterate(struct pa_simple *p, int block, int *perror) {
         
     } while (pa_context_is_pending(p->context));
 
+    
+    while (pa_mainloop_deferred_pending(p->mainloop)) {
+
+        if (pa_mainloop_iterate(p->mainloop, 0, NULL) < 0) {
+            if (perror)
+                *perror = PA_ERROR_INTERNAL;
+            return -1;
+        }
+
+        if (check_error(p, perror) < 0)
+            return -1;
+    }
+    
     return 0;
 }