summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2004-08-05 19:53:57 +0000
committerLennart Poettering <lennart@poettering.net>2004-08-05 19:53:57 +0000
commit964bdfd1e8255b57e9d22cd22b3784e2fc79b905 (patch)
tree11676e2930adb42af6ac00e721c4b2a73baf35ef
parent839f99ffbf5b01e585845a061830a6fa5f0743dc (diff)
add initial glib mainloop adapter
clean up mainloop API git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@105 fefdeb5f-60dc-0310-8127-8f9354f1896f
-rw-r--r--configure.ac4
-rw-r--r--polyp/Makefile.am7
-rw-r--r--polyp/alsa-util.c34
-rw-r--r--polyp/alsa-util.h4
-rw-r--r--polyp/core.c1
-rw-r--r--polyp/core.h2
-rw-r--r--polyp/glib-mainloop.c503
-rw-r--r--polyp/glib-mainloop.h14
-rw-r--r--polyp/iochannel.c60
-rw-r--r--polyp/main.c11
-rw-r--r--polyp/mainloop-api.c34
-rw-r--r--polyp/mainloop-api.h48
-rw-r--r--polyp/mainloop-signal.c99
-rw-r--r--polyp/mainloop-signal.h8
-rw-r--r--polyp/mainloop.c616
-rw-r--r--polyp/module-alsa-sink.c14
-rw-r--r--polyp/module-alsa-source.c14
-rw-r--r--polyp/module-oss-mmap.c19
-rw-r--r--polyp/module-pipe-sink.c16
-rw-r--r--polyp/module-x11-bell.c10
-rw-r--r--polyp/module.c20
-rw-r--r--polyp/module.h1
-rw-r--r--polyp/native-common.h16
-rw-r--r--polyp/pacat.c46
-rw-r--r--polyp/pactl.c4
-rw-r--r--polyp/pdispatch.c12
-rw-r--r--polyp/play-memchunk.c2
-rwxr-xr-xpolyp/polypaudio.pa30
-rw-r--r--polyp/polyplib.h30
-rw-r--r--polyp/protocol-esound.c35
-rw-r--r--polyp/protocol-native.c122
-rw-r--r--polyp/protocol-simple.c30
-rw-r--r--polyp/pstream.c18
-rw-r--r--polyp/socket-client.c39
-rw-r--r--polyp/socket-server.c12
-rw-r--r--polyp/xmalloc.h1
36 files changed, 1310 insertions, 626 deletions
diff --git a/configure.ac b/configure.ac
index 9e5352a5..3183d174 100644
--- a/configure.ac
+++ b/configure.ac
@@ -54,6 +54,10 @@ PKG_CHECK_MODULES(ASOUNDLIB, [ alsa >= 1.0.0 ])
AC_SUBST(ASOUNDLIB_CFLAGS)
AC_SUBST(ASOUNDLIB_LIBS)
+PKG_CHECK_MODULES(GLIB20, [ glib-2.0 >= 2.4.0 ])
+AC_SUBST(GLIB20_CFLAGS)
+AC_SUBST(GLIB20_LIBS)
+
# If using GCC specifiy some additional parameters
if test "x$GCC" = "xyes" ; then
CFLAGS="$CFLAGS -pipe -Wall -W -Wno-unused-parameter"
diff --git a/polyp/Makefile.am b/polyp/Makefile.am
index 0af99110..c0be8ce0 100644
--- a/polyp/Makefile.am
+++ b/polyp/Makefile.am
@@ -71,7 +71,8 @@ pkglib_LTLIBRARIES=libiochannel.la \
lib_LTLIBRARIES=libpolyp.la \
libpolyp-simple.la \
libpolyp-error.la \
- libpolyp-mainloop.la
+ libpolyp-mainloop.la \
+ libpolyp-mainloop-glib.la
polypaudio_SOURCES = idxset.c idxset.h \
queue.c queue.h \
@@ -307,6 +308,10 @@ parec_simple_SOURCES = parec-simple.c
parec_simple_LDADD = $(AM_LDADD) libpolyp-simple.la libpolyp-error.la
parec_simple_CFLAGS = $(AM_CFLAGS)
+libpolyp_mainloop_glib_la_SOURCES = glib-mainloop.h glib-mainloop.c
+libpolyp_mainloop_glib_la_CFLAGS = $(AM_CFLAGS) $(GLIB20_CFLAGS)
+libpolyp_mainloop_glib_la_LIBADD = $(AM_LIBADD) libpolyp-mainloop.la $(GLIB20_LIBS)
+
if BUILD_LIBPOLYPCORE
pkginclude_HEADERS+=cli-command.h\
diff --git a/polyp/alsa-util.c b/polyp/alsa-util.c
index 43562378..70e2e072 100644
--- a/polyp/alsa-util.c
+++ b/polyp/alsa-util.c
@@ -59,26 +59,26 @@ int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, struct pa_sample_spec *ss, uint
return ret;
}
-int pa_create_io_sources(snd_pcm_t *pcm_handle, struct pa_mainloop_api* m, void ***io_sources, unsigned *n_io_sources, void (*cb)(struct pa_mainloop_api*a, void *id, int fd, enum pa_mainloop_api_io_events events, void *userdata), void *userdata) {
+int pa_create_io_events(snd_pcm_t *pcm_handle, struct pa_mainloop_api* m, struct pa_io_event ***io_events, unsigned *n_io_events, void (*cb)(struct pa_mainloop_api*a, struct pa_io_event *e, int fd, enum pa_io_event_flags events, void *userdata), void *userdata) {
unsigned i;
struct pollfd *pfds, *ppfd;
- void **ios;
- assert(pcm_handle && m && io_sources && n_io_sources && cb);
+ struct pa_io_event **ios;
+ assert(pcm_handle && m && io_events && n_io_events && cb);
- *n_io_sources = snd_pcm_poll_descriptors_count(pcm_handle);
+ *n_io_events = snd_pcm_poll_descriptors_count(pcm_handle);
- pfds = pa_xmalloc(sizeof(struct pollfd) * *n_io_sources);
- if (snd_pcm_poll_descriptors(pcm_handle, pfds, *n_io_sources) < 0) {
+ pfds = pa_xmalloc(sizeof(struct pollfd) * *n_io_events);
+ if (snd_pcm_poll_descriptors(pcm_handle, pfds, *n_io_events) < 0) {
pa_xfree(pfds);
return -1;
}
- *io_sources = pa_xmalloc(sizeof(void*) * *n_io_sources);
+ *io_events = pa_xmalloc(sizeof(void*) * *n_io_events);
- for (i = 0, ios = *io_sources, ppfd = pfds; i < *n_io_sources; i++, ios++, ppfd++) {
- *ios = m->source_io(m, ppfd->fd,
- ((ppfd->events & POLLIN) ? PA_MAINLOOP_API_IO_EVENT_INPUT : 0) |
- ((ppfd->events & POLLOUT) ? PA_MAINLOOP_API_IO_EVENT_OUTPUT : 0), cb, userdata);
+ for (i = 0, ios = *io_events, ppfd = pfds; i < *n_io_events; i++, ios++, ppfd++) {
+ *ios = m->io_new(m, ppfd->fd,
+ ((ppfd->events & POLLIN) ? PA_IO_EVENT_INPUT : 0) |
+ ((ppfd->events & POLLOUT) ? PA_IO_EVENT_OUTPUT : 0), cb, userdata);
assert(*ios);
}
@@ -86,12 +86,12 @@ int pa_create_io_sources(snd_pcm_t *pcm_handle, struct pa_mainloop_api* m, void
return 0;
}
-void pa_free_io_sources(struct pa_mainloop_api* m, void **io_sources, unsigned n_io_sources) {
+void pa_free_io_events(struct pa_mainloop_api* m, struct pa_io_event **io_events, unsigned n_io_events) {
unsigned i;
- void **ios;
- assert(m && io_sources);
+ struct pa_io_event **ios;
+ assert(m && io_events);
- for (ios = io_sources, i = 0; i < n_io_sources; i++, ios++)
- m->cancel_io(m, *ios);
- pa_xfree(io_sources);
+ for (ios = io_events, i = 0; i < n_io_events; i++, ios++)
+ m->io_free(*ios);
+ pa_xfree(io_events);
}
diff --git a/polyp/alsa-util.h b/polyp/alsa-util.h
index 03e427d9..2627a75c 100644
--- a/polyp/alsa-util.h
+++ b/polyp/alsa-util.h
@@ -29,7 +29,7 @@
int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, struct pa_sample_spec *ss, uint32_t *periods, snd_pcm_uframes_t *buffer_size);
-int pa_create_io_sources(snd_pcm_t *pcm_handle, struct pa_mainloop_api *m, void ***io_sources, unsigned *n_io_sources, void (*cb)(struct pa_mainloop_api*a, void *id, int fd, enum pa_mainloop_api_io_events events, void *userdata), void *userdata);
-void pa_free_io_sources(struct pa_mainloop_api* m, void **io_sources, unsigned n_io_sources);
+int pa_create_io_events(snd_pcm_t *pcm_handle, struct pa_mainloop_api *m, struct pa_io_event ***io_events, unsigned *n_io_events, void (*cb)(struct pa_mainloop_api*a, struct pa_io_event *e, int fd, enum pa_io_event_flags events, void *userdata), void *userdata);
+void pa_free_io_events(struct pa_mainloop_api* m, struct pa_io_event **io_sources, unsigned n_io_sources);
#endif
diff --git a/polyp/core.c b/polyp/core.c
index ffc11cec..0444fa96 100644
--- a/polyp/core.c
+++ b/polyp/core.c
@@ -62,6 +62,7 @@ struct pa_core* pa_core_new(struct pa_mainloop_api *m) {
c->default_sample_spec.channels = 2;
c->auto_unload_time = 20;
+ c->auto_unload_event = NULL;
pa_check_for_sigpipe();
diff --git a/polyp/core.h b/polyp/core.h
index b125083d..e1e48cbc 100644
--- a/polyp/core.h
+++ b/polyp/core.h
@@ -38,7 +38,7 @@ struct pa_core {
struct pa_sample_spec default_sample_spec;
int auto_unload_time;
- void *auto_unload_mainloop_source;
+ struct pa_time_event *auto_unload_event;
};
struct pa_core* pa_core_new(struct pa_mainloop_api *m);
diff --git a/polyp/glib-mainloop.c b/polyp/glib-mainloop.c
new file mode 100644
index 00000000..978cad07
--- /dev/null
+++ b/polyp/glib-mainloop.c
@@ -0,0 +1,503 @@
+#include <assert.h>
+
+#include "glib-mainloop.h"
+#include "idxset.h"
+#include "xmalloc.h"
+
+struct pa_io_event {
+ GSource source;
+ int dead;
+ struct pa_glib_mainloop *mainloop;
+ int fd;
+ GPollFD pollfd;
+ void (*callback) (struct pa_mainloop_api*m, struct pa_io_event *e, int fd, enum pa_io_event_flags f, void *userdata);
+ void *userdata;
+ void (*destroy_callback) (struct pa_mainloop_api *m, struct pa_io_event*e, void *userdata);
+ struct pa_io_event *next, *prev;
+};
+
+struct pa_time_event {
+ struct pa_glib_mainloop *mainloop;
+ int dead;
+ GSource *source;
+ struct timeval timeval;
+ void (*callback) (struct pa_mainloop_api*m, struct pa_time_event *e, const struct timeval *tv, void *userdata);
+ void *userdata;
+ void (*destroy_callback) (struct pa_mainloop_api *m, struct pa_time_event*e, void *userdata);
+ struct pa_time_event *next, *prev;
+};
+
+struct pa_defer_event {
+ struct pa_glib_mainloop *mainloop;
+ int dead;
+ GSource *source;
+ void (*callback) (struct pa_mainloop_api*m, struct pa_defer_event *e, void *userdata);
+ void *userdata;
+ void (*destroy_callback) (struct pa_mainloop_api *m, struct pa_defer_event*e, void *userdata);
+ struct pa_defer_event *next, *prev;
+};
+
+struct pa_glib_mainloop {
+ GMainLoop *glib_mainloop;
+ struct pa_mainloop_api api;
+ GSource *cleanup_source;
+ struct pa_io_event *io_events, *dead_io_events;
+ struct pa_time_event *time_events, *dead_time_events;
+ struct pa_defer_event *defer_events, *dead_defer_events;
+};
+
+static void schedule_free_dead_events(struct pa_glib_mainloop *g);
+
+static gboolean glib_source_prepare(GSource *source, gint *timeout) {
+ return FALSE;
+}
+
+static gboolean glib_source_check(GSource *source) {
+ struct pa_io_event *e = (struct pa_io_event*) source;
+ assert(e);
+ return !!e->pollfd.revents;
+}
+
+static gboolean glib_source_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) {
+ struct pa_io_event *e = (struct pa_io_event*) source;
+ assert(e);
+
+ if (e->pollfd.revents) {
+ int f =
+ (e->pollfd.revents ? G_IO_IN : PA_IO_EVENT_INPUT) |
+ (e->pollfd.revents ? G_IO_OUT : PA_IO_EVENT_OUTPUT) |
+ (e->pollfd.revents ? G_IO_HUP : PA_IO_EVENT_HANGUP) |
+ (e->pollfd.revents ? G_IO_ERR : PA_IO_EVENT_ERROR);
+ e->pollfd.revents = 0;
+
+ assert(e->callback);
+ e->callback(&e->mainloop->api, e, e->fd, f, e->userdata);
+ }
+
+ return TRUE;
+}
+
+static void glib_io_enable(struct pa_io_event*e, enum pa_io_event_flags f);
+
+static struct pa_io_event* glib_io_new(struct pa_mainloop_api*m, int fd, enum pa_io_event_flags f, void (*callback) (struct pa_mainloop_api*m, struct pa_io_event*e, int fd, enum pa_io_event_flags f, void *userdata), void *userdata) {
+ struct pa_io_event *e;
+ struct pa_glib_mainloop *g;
+
+ GSourceFuncs io_source_funcs = {
+ prepare: glib_source_prepare,
+ check: glib_source_check,
+ dispatch: glib_source_dispatch,
+ finalize: NULL,
+ closure_callback: NULL,
+ closure_marshal : NULL,
+ };
+
+ assert(m && m->userdata && fd >= 0 && callback);
+ g = m->userdata;
+
+ e = (struct pa_io_event*) g_source_new(&io_source_funcs, sizeof(struct pa_io_event));
+ assert(e);
+ e->mainloop = m->userdata;
+ e->dead = 0;
+ e->fd = fd;
+ e->callback = callback;
+ e->userdata = userdata;
+ e->destroy_callback = NULL;
+
+ e->pollfd.fd = fd;
+ e->pollfd.events = e->pollfd.revents = 0;
+
+ g_source_attach(&e->source, g_main_loop_get_context(g->glib_mainloop));
+
+ glib_io_enable(e, f);
+
+ e->next = g->io_events;
+ if (e->next) e->next->prev = e;
+ g->io_events = e;
+ e->prev = NULL;
+
+ return e;
+}
+
+static void glib_io_enable(struct pa_io_event*e, enum pa_io_event_flags f) {
+ int o;
+ assert(e && !e->dead);
+
+ o = e->pollfd.events;
+ e->pollfd.events = (f & PA_IO_EVENT_INPUT ? G_IO_IN : 0) | (f & PA_IO_EVENT_OUTPUT ? G_IO_OUT : 0) | G_IO_HUP | G_IO_ERR;
+
+ if (!o && e->pollfd.events)
+ g_source_add_poll(&e->source, &e->pollfd);
+ else if (o && !e->pollfd.events)
+ g_source_remove_poll(&e->source, &e->pollfd);
+}
+
+static void glib_io_free(struct pa_io_event*e) {
+ assert(e && !e->dead);
+
+ g_source_destroy(&e->source);
+
+ if (e->prev)
+ e->prev->next = e->next;
+ else
+ e->mainloop->io_events = e->next;
+
+ if (e->next)
+ e->next->prev = e->prev;
+
+ if ((e->next = e->mainloop->dead_io_events))
+ e->next->prev = e;
+
+ e->mainloop->dead_io_events = e;
+ e->prev = NULL;
+
+ e->dead = 1;
+ schedule_free_dead_events(e->mainloop);
+}
+
+static void glib_io_set_destroy(struct pa_io_event*e, void (*callback)(struct pa_mainloop_api*m, struct pa_io_event *e, void *userdata)) {
+ assert(e);
+ e->destroy_callback = callback;
+}
+
+/* Time sources */
+
+static void glib_time_restart(struct pa_time_event*e, const struct timeval *tv);
+
+static struct pa_time_event* glib_time_new(struct pa_mainloop_api*m, const struct timeval *tv, void (*callback) (struct pa_mainloop_api*m, struct pa_time_event*e, const struct timeval *tv, void *userdata), void *userdata) {
+ struct pa_glib_mainloop *g;
+ struct pa_time_event *e;
+
+ assert(m && m->userdata && tv && callback);
+ g = m->userdata;
+
+ e = pa_xmalloc(sizeof(struct pa_time_event));
+ e->mainloop = g;
+ e->dead = 0;
+ e->callback = callback;
+ e->userdata = userdata;
+ e->destroy_callback = NULL;
+ e->source = NULL;
+
+ glib_time_restart(e, tv);
+
+ e->next = g->time_events;
+ if (e->next) e->next->prev = e;
+ g->time_events = e;
+ e->prev = NULL;
+
+ return e;
+}
+
+static guint msec_diff(const struct timeval *a, const struct timeval *b) {
+ guint r;
+ assert(a && b);
+
+ if (a->tv_sec < b->tv_sec)
+ return 0;
+
+ if (a->tv_sec == b->tv_sec && a->tv_sec <= b->tv_sec)
+ return 0;
+
+ r = (a->tv_sec-b->tv_sec)*1000;
+
+ if (a->tv_usec >= b->tv_usec)
+ r += (a->tv_usec - b->tv_usec) / 1000;
+ else
+ r -= (b->tv_usec - a->tv_usec) / 1000;
+
+ return r;
+}
+
+static gboolean time_cb(gpointer data) {
+ struct pa_time_event* e = data;
+ assert(e && e->mainloop && e->source);
+
+ g_source_unref(e->source);
+ e->source = NULL;
+
+ e->callback(&e->mainloop->api, e, &e->timeval, e->userdata);
+ return FALSE;
+}
+
+static void glib_time_restart(struct pa_time_event*e, const struct timeval *tv) {
+ struct timeval now;
+ assert(e && e->mainloop);
+
+ gettimeofday(&now, NULL);
+ if (e->source) {
+ g_source_destroy(e->source);
+ g_source_unref(e->source);
+ }
+
+ if (tv) {
+ e->timeval = *tv;
+ e->source = g_timeout_source_new(msec_diff(tv, &now));
+ assert(e->source);
+ g_source_set_callback(e->source, time_cb, e, NULL);
+ g_source_attach(e->source, g_main_loop_get_context(e->mainloop->glib_mainloop));
+ } else
+ e->source = NULL;
+ }
+
+static void glib_time_free(struct pa_time_event *e) {
+ assert(e && e->mainloop);
+
+ if (e->source) {
+ g_source_destroy(e->source);
+ g_source_unref(e->source);
+ e->source = NULL;
+ }
+
+ if (e->prev)
+ e->prev->next = e->next;
+ else
+ e->mainloop->time_events = e->next;
+
+ if (e->next)
+ e->next->prev = e->prev;
+
+ if ((e->next = e->mainloop->dead_time_events))
+ e->next->prev = e;
+
+ e->mainloop->dead_time_events = e;
+ e->prev = NULL;
+
+ e->dead = 1;
+ schedule_free_dead_events(e->mainloop);
+}
+
+static void glib_time_set_destroy(struct pa_time_event *e, void (*callback)(struct pa_mainloop_api*m, struct pa_time_event*e, void *userdata)) {
+ assert(e);
+ e->destroy_callback = callback;
+}
+
+/* Deferred sources */
+
+static void glib_defer_enable(struct pa_defer_event *e, int b);
+
+static struct pa_defer_event* glib_defer_new(struct pa_mainloop_api*m, void (*callback) (struct pa_mainloop_api*m, struct pa_defer_event *e, void *userdata), void *userdata) {
+ struct pa_defer_event *e;
+ struct pa_glib_mainloop *g;
+
+ assert(m && m->userdata && callback);
+ g = m->userdata;
+
+ e = pa_xmalloc(sizeof(struct pa_defer_event));
+ e->mainloop = g;
+ e->dead = 0;
+ e->callback = callback;
+ e->userdata = userdata;
+ e->destroy_callback = NULL;
+ e->source = NULL;
+
+ glib_defer_enable(e, 1);
+
+ e->next = g->defer_events;
+ if (e->next) e->next->prev = e;
+ g->defer_events = e;
+ e->prev = NULL;
+ return e;
+}
+
+static gboolean idle_cb(gpointer data) {
+ struct pa_defer_event* e = data;
+ assert(e && e->mainloop && e->source);
+
+ e->callback(&e->mainloop->api, e, e->userdata);
+ return TRUE;
+}
+
+static void glib_defer_enable(struct pa_defer_event *e, int b) {
+ assert(e && e->mainloop);
+
+ if (e->source && !b) {
+ g_source_destroy(e->source);
+ g_source_unref(e->source);
+ e->source = NULL;
+ } else if (!e->source && b) {
+ e->source = g_idle_source_new();
+ assert(e->source);
+ g_source_set_callback(e->source, idle_cb, e, NULL);
+ g_source_attach(e->source, g_main_loop_get_context(e->mainloop->glib_mainloop));
+ g_source_set_priority(e->source, G_PRIORITY_HIGH_IDLE);
+ }
+}
+
+static void glib_defer_free(struct pa_defer_event *e) {
+ assert(e && e->mainloop);
+
+ if (e->source) {
+ g_source_destroy(e->source);
+ g_source_unref(e->source);
+ e->source = NULL;
+ }
+
+ if (e->prev)
+ e->prev->next = e->next;
+ else
+ e->mainloop->defer_events = e->next;
+
+ if (e->next)
+ e->next->prev = e->prev;
+
+ if ((e->next = e->mainloop->dead_defer_events))
+ e->next->prev = e;
+
+ e->mainloop->dead_defer_events = e;
+ e->prev = NULL;
+
+ e->dead = 1;
+ schedule_free_dead_events(e->mainloop);
+}
+
+static void glib_defer_set_destroy(struct pa_defer_event *e, void (*callback)(struct pa_mainloop_api *m, struct pa_defer_event *e, void *userdata)) {
+ assert(e);
+ e->destroy_callback = callback;
+}
+
+/* quit() */
+
+static void glib_quit(struct pa_mainloop_api*a, int retval) {
+ struct pa_glib_mainloop *g;
+ assert(a && a->userdata);
+ g = a->userdata;
+
+ g_main_loop_quit(g->glib_mainloop);
+}
+
+static const struct pa_mainloop_api vtable = {
+ userdata: NULL,
+
+ io_new: glib_io_new,
+ io_enable: glib_io_enable,
+ io_free: glib_io_free,
+ io_set_destroy: glib_io_set_destroy,
+
+ time_new : glib_time_new,
+ 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,
+};
+
+struct pa_glib_mainloop *pa_glib_mainloop_new(GMainLoop *ml) {
+ struct pa_glib_mainloop *g;
+ assert(ml);
+
+ g = pa_xmalloc(sizeof(struct pa_glib_mainloop));
+ g->glib_mainloop = g_main_loop_ref(ml);
+ g->api = vtable;
+ g->api.userdata = g;
+
+ g->io_events = g->dead_io_events = NULL;
+ g->time_events = g->dead_time_events = NULL;
+ g->defer_events = g->dead_defer_events = NULL;
+
+ g->cleanup_source = NULL;
+ return g;
+}
+
+static void free_io_events(struct pa_io_event *e) {
+ while (e) {
+ struct pa_io_event *r = e;
+ e = r->next;
+
+ if (r->pollfd.events)
+ g_source_remove_poll(&r->source, &r->pollfd);
+
+ if (!r->dead)
+ g_source_destroy(&r->source);
+
+ if (r->destroy_callback)
+ r->destroy_callback(&r->mainloop->api, r, r->userdata);
+
+ g_source_unref(&r->source);
+ }
+}
+
+static void free_time_events(struct pa_time_event *e) {
+ while (e) {
+ struct pa_time_event *r = e;
+ e = r->next;
+
+ if (r->source) {
+ g_source_destroy(r->source);
+ g_source_unref(r->source);
+ }
+
+ if (r->destroy_callback)
+ r->destroy_callback(&r->mainloop->api, r, r->userdata);
+
+ pa_xfree(r);
+ }
+}
+
+static void free_defer_events(struct pa_defer_event *e) {
+ while (e) {
+ struct pa_defer_event *r = e;
+ e = r->next;
+
+ if (r->source) {
+ g_source_destroy(r->source);
+ g_source_unref(r->source);
+ }
+
+ if (r->destroy_callback)
+ r->destroy_callback(&r->mainloop->api, r, r->userdata);
+
+ pa_xfree(r);
+ }
+}
+
+void pa_glib_mainloop_free(struct pa_glib_mainloop* g) {
+ assert(g);
+
+ free_io_events(g->io_events);
+ free_io_events(g->dead_io_events);
+ free_defer_events(g->defer_events);
+ free_defer_events(g->dead_defer_events);
+ free_time_events(g->time_events);
+ free_time_events(g->dead_time_events);
+
+ g_main_loop_unref(g->glib_mainloop);
+ pa_xfree(g);
+}
+
+struct pa_mainloop_api* pa_glib_mainloop_get_api(struct pa_glib_mainloop *g) {
+ assert(g);
+ return &g->api;
+}
+
+static gboolean free_dead_events(gpointer p) {
+ struct pa_glib_mainloop *g = p;
+ assert(g);
+
+ free_io_events(g->dead_io_events);
+ free_defer_events(g->dead_defer_events);
+ free_time_events(g->dead_time_events);
+
+ g_source_destroy(g->cleanup_source);
+ g_source_unref(g->cleanup_source);
+ g->cleanup_source = NULL;
+
+ return FALSE;
+}
+
+static void schedule_free_dead_events(struct pa_glib_mainloop *g) {
+ assert(g && g->glib_mainloop);
+
+ if (g->cleanup_source)
+ return;
+
+ g->cleanup_source = g_idle_source_new();
+ assert(g->cleanup_source);
+ g_source_set_callback(g->cleanup_source, free_dead_events, g, NULL);
+ g_source_attach(g->cleanup_source, g_main_loop_get_context(g->glib_mainloop));
+}
diff --git a/polyp/glib-mainloop.h b/polyp/glib-mainloop.h
new file mode 100644
index 00000000..50fe8b9c
--- /dev/null
+++ b/polyp/glib-mainloop.h
@@ -0,0 +1,14 @@
+#ifndef fooglibmainloophfoo
+#define fooglibmainloophfoo
+
+#include <glib.h>
+
+#include "mainloop-api.h"
+
+struct pa_glib_mainloop;
+
+struct pa_glib_mainloop *pa_glib_mainloop_new(GMainLoop *ml);
+void pa_glib_mainloop_free(struct pa_glib_mainloop* g);
+struct pa_mainloop_api* pa_glib_mainloop_get_api(struct pa_glib_mainloop *g);
+
+#endif
diff --git a/polyp/iochannel.c b/polyp/iochannel.c
index 77f8fb08..813347d4 100644
--- a/polyp/iochannel.c
+++ b/polyp/iochannel.c
@@ -46,50 +46,50 @@ struct pa_iochannel {
int no_close;
- void* input_source, *output_source;
+ struct pa_io_event* input_event, *output_event;
};
static void enable_mainloop_sources(struct pa_iochannel *io) {
assert(io);
- if (io->input_source == io->output_source) {
- enum pa_mainloop_api_io_events e = PA_MAINLOOP_API_IO_EVENT_NULL;
- assert(io->input_source);
+ if (io->input_event == io->output_event) {
+ enum pa_io_event_flags f = PA_IO_EVENT_NULL;
+ assert(io->input_event);
if (!io->readable)
- e |= PA_MAINLOOP_API_IO_EVENT_INPUT;
+ f |= PA_IO_EVENT_INPUT;
if (!io->writable)
- e |= PA_MAINLOOP_API_IO_EVENT_OUTPUT;
+ f |= PA_IO_EVENT_OUTPUT;
- io->mainloop->enable_io(io->mainloop, io->input_source, e);
+ io->mainloop->io_enable(io->input_event, f);
} else {
- if (io->input_source)
- io->mainloop->enable_io(io->mainloop, io->input_source, io->readable ? PA_MAINLOOP_API_IO_EVENT_NULL : PA_MAINLOOP_API_IO_EVENT_INPUT);
- if (io->output_source)
- io->mainloop->enable_io(io->mainloop, io->output_source, io->writable ? PA_MAINLOOP_API_IO_EVENT_NULL : PA_MAINLOOP_API_IO_EVENT_OUTPUT);
+ if (io->input_event)
+ io->mainloop->io_enable(io->input_event, io->readable ? PA_IO_EVENT_NULL : PA_IO_EVENT_INPUT);
+ if (io->output_event)
+ io->mainloop->io_enable(io->output_event, io->writable ? PA_IO_EVENT_NULL : PA_IO_EVENT_OUTPUT);
}
}
-static void callback(struct pa_mainloop_api* m, void *id, int fd, enum pa_mainloop_api_io_events events, void *userdata) {
+static void callback(struct pa_mainloop_api* m, struct pa_io_event *e, int fd, enum pa_io_event_flags f, void *userdata) {
struct pa_iochannel *io = userdata;
int changed = 0;
- assert(m && fd >= 0 && events && userdata);
+ assert(m && e && fd >= 0 && userdata);
- if ((events & PA_MAINLOOP_API_IO_EVENT_HUP) && !io->hungup) {
+ if ((f & (PA_IO_EVENT_HANGUP|PA_IO_EVENT_ERROR)) && !io->hungup) {
io->hungup = 1;
changed = 1;
}
- if ((events & PA_MAINLOOP_API_IO_EVENT_INPUT) && !io->readable) {
+ if ((f & PA_IO_EVENT_INPUT) && !io->readable) {
io->readable = 1;
changed = 1;
- assert(id == io->input_source);
+ assert(e == io->input_event);
}
- if ((events & PA_MAINLOOP_API_IO_EVENT_OUTPUT) && !io->writable) {
+ if ((f & PA_IO_EVENT_OUTPUT) && !io->writable) {
io->writable = 1;
changed = 1;
- assert(id == io->output_source);
+ assert(e == io->output_event);
}
if (changed) {
@@ -116,23 +116,23 @@ struct pa_iochannel* pa_iochannel_new(struct pa_mainloop_api*m, int ifd, int ofd
io->hungup = 0;
io->no_close = 0;
+ io->input_event = io->output_event = NULL;
+
if (ifd == ofd) {
assert(ifd >= 0);
pa_make_nonblock_fd(io->ifd);
- io->input_source = io->output_source = m->source_io(m, ifd, PA_MAINLOOP_API_IO_EVENT_BOTH, callback, io);
+ io->input_event = io->output_event = m->io_new(m, ifd, PA_IO_EVENT_INPUT|PA_IO_EVENT_OUTPUT, callback, io);
} else {
if (ifd >= 0) {
pa_make_nonblock_fd(io->ifd);
- io->input_source = m->source_io(m, ifd, PA_MAINLOOP_API_IO_EVENT_INPUT, callback, io);
- } else
- io->input_source = NULL;
+ io->input_event = m->io_new(m, ifd, PA_IO_EVENT_INPUT, callback, io);
+ }
if (ofd >= 0) {
pa_make_nonblock_fd(io->ofd);
- io->output_source = m->source_io(m, ofd, PA_MAINLOOP_API_IO_EVENT_OUTPUT, callback, io);
- } else
- io->output_source = NULL;
+ io->output_event = m->io_new(m, ofd, PA_IO_EVENT_OUTPUT, callback, io);
+ }
}
return io;
@@ -141,17 +141,17 @@ struct pa_iochannel* pa_iochannel_new(struct pa_mainloop_api*m, int ifd, int ofd
void pa_iochannel_free(struct pa_iochannel*io) {
assert(io);
+ if (io->input_event)
+ io->mainloop->io_free(io->input_event);
+ if (io->output_event && (io->output_event != io->input_event))
+ io->mainloop->io_free(io->output_event);
+
if (!io->no_close) {
if (io->ifd >= 0)
close(io->ifd);
if (io->ofd >= 0 && io->ofd != io->ifd)
close(io->ofd);
}
-
- if (io->input_source)
- io->mainloop->cancel_io(io->mainloop, io->input_source);
- if (io->output_source && (io->output_source != io->input_source))
- io->mainloop->cancel_io(io->mainloop, io->output_source);
pa_xfree(io);
}
diff --git a/polyp/main.c b/polyp/main.c
index de66f1c8..9f3d3406 100644
--- a/polyp/main.c
+++ b/polyp/main.c
@@ -46,13 +46,12 @@
static struct pa_mainloop *mainloop;
-static void exit_signal_callback(void *id, int sig, void *userdata) {
- struct pa_mainloop_api* m = pa_mainloop_get_api(mainloop);
+static void exit_signal_callback(struct pa_mainloop_api*m, struct pa_signal_event *e, int sig, void *userdata) {
m->quit(m, 1);
fprintf(stderr, __FILE__": got signal.\n");
}
-static void aux_signal_callback(void *id, int sig, void *userdata) {
+static void aux_signal_callback(struct pa_mainloop_api*m, struct pa_signal_event *e, int sig, void *userdata) {
struct pa_core *c = userdata;
assert(c);
pa_module_load(c, sig == SIGUSR1 ? "module-cli" : "module-cli-protocol-unix", NULL);
@@ -135,14 +134,14 @@ int main(int argc, char *argv[]) {
r = pa_signal_init(pa_mainloop_get_api(mainloop));
assert(r == 0);
- pa_signal_register(SIGINT, exit_signal_callback, NULL);
+ pa_signal_new(SIGINT, exit_signal_callback, NULL);
signal(SIGPIPE, SIG_IGN);
c = pa_core_new(pa_mainloop_get_api(mainloop));
assert(c);
- pa_signal_register(SIGUSR1, aux_signal_callback, c);
- pa_signal_register(SIGUSR2, aux_signal_callback, c);
+ pa_signal_new(SIGUSR1, aux_signal_callback, c);
+ pa_signal_new(SIGUSR2, aux_signal_callback, c);
buf = pa_strbuf_new();
assert(buf);
diff --git a/polyp/mainloop-api.c b/polyp/mainloop-api.c
index 8b4e09ac..952fce0a 100644
--- a/polyp/mainloop-api.c
+++ b/polyp/mainloop-api.c
@@ -30,32 +30,38 @@
#include "xmalloc.h"
struct once_info {
- void (*callback)(void *userdata);
+ void (*callback)(struct pa_mainloop_api*m, void *userdata);
void *userdata;
};
-static void once_callback(struct pa_mainloop_api *api, void *id, void *userdata) {
+static void once_callback(struct pa_mainloop_api *m, struct pa_defer_event *e, void *userdata) {
struct once_info *i = userdata;
- assert(api && i && i->callback);
- i->callback(i->userdata);
- assert(api->cancel_fixed);
- api->cancel_fixed(api, id);
+ assert(m && i && i->callback);
+
+ i->callback(m, i->userdata);
+
+ assert(m->defer_free);
+ m->defer_free(e);
+}
+
+static void free_callback(struct pa_mainloop_api *m, struct pa_defer_event *e, void *userdata) {
+ struct once_info *i = userdata;
+ assert(m && i);
pa_xfree(i);
}
-void pa_mainloop_api_once(struct pa_mainloop_api* api, void (*callback)(void *userdata), void *userdata) {
+void pa_mainloop_api_once(struct pa_mainloop_api* m, void (*callback)(struct pa_mainloop_api *m, void *userdata), void *userdata) {
struct once_info *i;
- void *id;
- assert(api && callback);
+ struct pa_defer_event *e;
+ assert(m && callback);
i = pa_xmalloc(sizeof(struct once_info));
i->callback = callback;
i->userdata = userdata;
- assert(api->source_fixed);
- id = api->source_fixed(api, once_callback, i);
- assert(id);
-
- /* Note: if the mainloop is destroyed before once_callback() was called, some memory is leaked. */
+ assert(m->defer_new);
+ e = m->defer_new(m, once_callback, i);
+ assert(e);
+ m->defer_set_destroy(e, free_callback);
}
diff --git a/polyp/mainloop-api.h b/polyp/mainloop-api.h
index 0228f580..4c8e379b 100644
--- a/polyp/mainloop-api.h
+++ b/polyp/mainloop-api.h
@@ -25,41 +25,43 @@
#include <time.h>
#include <sys/time.h>
-enum pa_mainloop_api_io_events {
- PA_MAINLOOP_API_IO_EVENT_NULL = 0,
- PA_MAINLOOP_API_IO_EVENT_INPUT = 1,
- PA_MAINLOOP_API_IO_EVENT_OUTPUT = 2,
- PA_MAINLOOP_API_IO_EVENT_BOTH = 3,
- PA_MAINLOOP_API_IO_EVENT_HUP = 4
+enum pa_io_event_flags {
+ PA_IO_EVENT_NULL = 0,
+ PA_IO_EVENT_INPUT = 1,
+ PA_IO_EVENT_OUTPUT = 2,
+ PA_IO_EVENT_HANGUP = 4,
+ PA_IO_EVENT_ERROR = 8,
};
+struct pa_io_event;
+struct pa_defer_event;
+struct pa_time_event;
+
struct pa_mainloop_api {
void *userdata;
/* IO sources */
- void* (*source_io)(struct pa_mainloop_api*a, int fd, enum pa_mainloop_api_io_events events, void (*callback) (struct pa_mainloop_api*a, void *id, int fd, enum pa_mainloop_api_io_events events, void *userdata), void *userdata);
- void (*enable_io)(struct pa_mainloop_api*a, void* id, enum pa_mainloop_api_io_events events);
- void (*cancel_io)(struct pa_mainloop_api*a, void* id);
-
- /* Fixed sources */
- void* (*source_fixed)(struct pa_mainloop_api*a, void (*callback) (struct pa_mainloop_api*a, void *id, void *userdata), void *userdata);
- void (*enable_fixed)(struct pa_mainloop_api*a, void* id, int b);
- void (*cancel_fixed)(struct pa_mainloop_api*a, void* id);
+ struct pa_io_event* (*io_new)(struct pa_mainloop_api*a, int fd, enum pa_io_event_flags events, void (*callback) (struct pa_mainloop_api*a, struct pa_io_event* e, int fd, enum pa_io_event_flags events, void *userdata), void *userdata);
+ void (*io_enable)(struct pa_io_event* e, enum pa_io_event_flags events);
+ void (*io_free)(struct pa_io_event* e);
+ void (*io_set_destroy)(struct pa_io_event *e, void (*callback) (struct pa_mainloop_api*a, struct pa_io_event *e, void *userdata));
- /* Idle sources */
- void* (*source_idle)(struct pa_mainloop_api*a, void (*callback) (struct pa_mainloop_api*a, void *id, void *userdata), void *userdata);
- void (*enable_idle)(struct pa_mainloop_api*a, void* id, int b);
- void (*cancel_idle)(struct pa_mainloop_api*a, void* id);
-
/* Time sources */
- void* (*source_time)(struct pa_mainloop_api*a, const struct timeval *tv, void (*callback) (struct pa_mainloop_api*a, void *id, const struct timeval *tv, void *userdata), void *userdata);
- void (*enable_time)(struct pa_mainloop_api*a, void *id, const struct timeval *tv);
- void (*cancel_time)(struct pa_mainloop_api*a, void* id);
+ struct pa_time_event* (*time_new)(struct pa_mainloop_api*a, const struct timeval *tv, void (*callback) (struct pa_mainloop_api*a, struct pa_time_event* e, const struct timeval *tv, void *userdata), void *userdata);
+ void (*time_restart)(struct pa_time_event* e, const struct timeval *tv);
+ void (*time_free)(struct pa_time_event* e);
+ void (*time_set_destroy)(struct pa_time_event *e, void (*callback) (struct pa_mainloop_api*a, struct pa_time_event *e, void *userdata));
+
+ /* Deferred sources */
+ struct pa_defer_event* (*defer_new)(struct pa_mainloop_api*a, void (*callback) (struct pa_mainloop_api*a, struct pa_defer_event* e, void *userdata), void *userdata);
+ void (*defer_enable)(struct pa_defer_event* e, int b);
+ void (*defer_free)(struct pa_defer_event* e);
+ void (*defer_set_destroy)(struct pa_defer_event *e, void (*callback) (struct pa_mainloop_api*a, struct pa_defer_event *e, void *userdata));
/* Exit mainloop */
void (*quit)(struct pa_mainloop_api*a, int retval);
};
-void pa_mainloop_api_once(struct pa_mainloop_api*m, void (*callback)(void *userdata), void *userdata);
+void pa_mainloop_api_once(struct pa_mainloop_api*m, void (*callback)(struct pa_mainloop_api*m, void *userdata), void *userdata);
#endif
diff --git a/polyp/mainloop-signal.c b/polyp/mainloop-signal.c
index 6e79767a..f7ff7e93 100644
--- a/polyp/mainloop-signal.c
+++ b/polyp/mainloop-signal.c
@@ -35,30 +35,31 @@
#include "util.h"
#include "xmalloc.h"
-struct signal_info {
+struct pa_signal_event {
int sig;
struct sigaction saved_sigaction;
- void (*callback) (void *id, int signal, void *userdata);
+ void (*callback) (struct pa_mainloop_api*a, struct pa_signal_event *e, int signal, void *userdata);
void *userdata;
- struct signal_info *previous, *next;
+ void (*destroy_callback) (struct pa_mainloop_api*a, struct pa_signal_event*e, void *userdata);
+ struct pa_signal_event *previous, *next;
};
static struct pa_mainloop_api *api = NULL;
static int signal_pipe[2] = { -1, -1 };
-static void* mainloop_source = NULL;
-static struct signal_info *signals = NULL;
+static struct pa_io_event* io_event = NULL;
+static struct pa_signal_event *signals = NULL;
static void signal_handler(int sig) {
write(signal_pipe[1], &sig, sizeof(sig));
}
-static void callback(struct pa_mainloop_api*a, void *id, int fd, enum pa_mainloop_api_io_events events, void *userdata) {
- assert(a && id && events == PA_MAINLOOP_API_IO_EVENT_INPUT && id == mainloop_source && fd == signal_pipe[0]);
+static void callback(struct pa_mainloop_api*a, struct pa_io_event*e, int fd, enum pa_io_event_flags f, void *userdata) {
+ assert(a && e && f == PA_IO_EVENT_INPUT && e == io_event && fd == signal_pipe[0]);
for (;;) {
ssize_t r;
int sig;
- struct signal_info*s;
+ struct pa_signal_event*s;
if ((r = read(signal_pipe[0], &sig, sizeof(sig))) < 0) {
if (errno == EAGAIN)
@@ -76,14 +77,15 @@ static void callback(struct pa_mainloop_api*a, void *id, int fd, enum pa_mainloo
for (s = signals; s; s = s->next)
if (s->sig == sig) {
assert(s->callback);
- s->callback(s, sig, s->userdata);
+ s->callback(a, s, sig, s->userdata);
break;
}
}
}
int pa_signal_init(struct pa_mainloop_api *a) {
- assert(a);
+ assert(!api && a && signal_pipe[0] == -1 && signal_pipe[1] == -1 && !io_event);
+
if (pipe(signal_pipe) < 0) {
fprintf(stderr, "pipe() failed: %s\n", strerror(errno));
return -1;
@@ -93,71 +95,80 @@ int pa_signal_init(struct pa_mainloop_api *a) {
pa_make_nonblock_fd(signal_pipe[1]);
api = a;
- mainloop_source = api->source_io(api, signal_pipe[0], PA_MAINLOOP_API_IO_EVENT_INPUT, callback, NULL);
- assert(mainloop_source);
+ io_event = api->io_new(api, signal_pipe[0], PA_IO_EVENT_INPUT, callback, NULL);
+ assert(io_event);
return 0;
}
void pa_signal_done(void) {
- assert(api && signal_pipe[0] >= 0 && signal_pipe[1] >= 0 && mainloop_source);
+ assert(api && signal_pipe[0] >= 0 && signal_pipe[1] >= 0 && io_event);
+
+ while (signals)
+ pa_signal_free(signals);
- api->cancel_io(api, mainloop_source);
- mainloop_source = NULL;
+ api->io_free(io_event);
+ io_event = NULL;
close(signal_pipe[0]);
close(signal_pipe[1]);
signal_pipe[0] = signal_pipe[1] = -1;
- while (signals)
- pa_signal_unregister(signals);
-
api = NULL;
}
-void* pa_signal_register(int sig, void (*callback) (void *id, int signal, void *userdata), void *userdata) {
- struct signal_info *s = NULL;
+struct pa_signal_event* pa_signal_new(int sig, void (*callback) (struct pa_mainloop_api *api, struct pa_signal_event*e, int sig, void *userdata), void *userdata) {
+ struct pa_signal_event *e = NULL;
struct sigaction sa;
assert(sig > 0 && callback);
-
- for (s = signals; s; s = s->next)
- if (s->sig == sig)
+
+ for (e = signals; e; e = e->next)
+ if (e->sig == sig)
goto fail;
- s = pa_xmalloc(sizeof(struct signal_info));
- s->sig = sig;
- s->callback = callback;
- s->userdata = userdata;
+ e = pa_xmalloc(sizeof(struct pa_signal_event));
+ e->sig = sig;
+ e->callback = callback;
+ e->userdata = userdata;
+ e->destroy_callback = NULL;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = signal_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
- if (sigaction(sig, &sa, &s->saved_sigaction) < 0)
+ if (sigaction(sig, &sa, &e->saved_sigaction) < 0)
goto fail;
- s->previous = NULL;
- s->next = signals;
- signals = s;
+ e->previous = NULL;
+ e->next = signals;
+ signals = e;
- return s;
+ return e;
fail:
- if (s)
- pa_xfree(s);
+ if (e)
+ pa_xfree(e);
return NULL;
}
-void pa_signal_unregister(void *id) {
- struct signal_info *s = id;
- assert(s);
+void pa_signal_free(struct pa_signal_event *e) {
+ assert(e);
- if (s->next)
- s->next->previous = s->previous;
- if (s->previous)
- s->previous->next = s->next;
+ if (e->next)
+ e->next->previous = e->previous;
+ if (e->previous)
+ e->previous->next = e->next;
else
- signals = s->next;
+ signals = e->next;
+
+ sigaction(e->sig, &e->saved_sigaction, NULL);
+
+ if (e->destroy_callback)
+ e->destroy_callback(api, e, e->userdata);
+
+ pa_xfree(e);
+}
- sigaction(s->sig, &s->saved_sigaction, NULL);
- pa_xfree(s);
+void pa_signal_set_destroy(struct pa_signal_event *e, void (*callback) (struct pa_mainloop_api *api, struct pa_signal_event*e, void *userdata)) {
+ assert(e);
+ e->destroy_callback = callback;
}
diff --git a/polyp/mainloop-signal.h b/polyp/mainloop-signal.h
index 8afe9c8d..dacbc153 100644
--- a/polyp/mainloop-signal.h
+++ b/polyp/mainloop-signal.h
@@ -27,7 +27,11 @@
int pa_signal_init(struct pa_mainloop_api *api);
void pa_signal_done(void);
-void* pa_signal_register(int signal, void (*callback) (void *id, int signal, void *userdata), void *userdata);
-void pa_signal_unregister(void *id);
+struct pa_signal_event;
+
+struct pa_signal_event* pa_signal_new(int signal, void (*callback) (struct pa_mainloop_api *api, struct pa_signal_event*e, int signal, void *userdata), void *userdata);
+void pa_signal_free(struct pa_signal_event *e);
+
+void pa_signal_set_destroy(struct pa_signal_event *e, void (*callback) (struct pa_mainloop_api *api, struct pa_signal_event*e, void *userdata));
#endif
diff --git a/polyp/mainloop.c b/polyp/mainloop.c
index f3d8e781..c678537e 100644
--- a/polyp/mainloop.c
+++ b/polyp/mainloop.c
@@ -38,42 +38,42 @@
#include "idxset.h"
#include "xmalloc.h"
-struct mainloop_source_header {
+struct pa_base_event {
+};
+
+struct pa_io_event {
struct pa_mainloop *mainloop;
int dead;
-};
-
-struct mainloop_source_io {
- struct mainloop_source_header header;
-
int fd;
- enum pa_mainloop_api_io_events events;
- void (*callback) (struct pa_mainloop_api*a, void *id, int fd, enum pa_mainloop_api_io_events events, void *userdata);
- void *userdata;
-
+ enum pa_io_event_flags events;
+ void (*callback) (struct pa_mainloop_api*a, struct pa_io_event *e, int fd, enum pa_io_event_flags f, void *userdata);
struct pollfd *pollfd;
+ void *userdata;
+ void (*destroy_callback) (struct pa_mainloop_api*a, struct pa_io_event *e, void *userdata);
};
-struct mainloop_source_fixed_or_idle {
- struct mainloop_source_header header;
+struct pa_time_event {
+ struct pa_mainloop *mainloop;
+ int dead;
int enabled;
-
- void (*callback)(struct pa_mainloop_api*a, void *id, void *userdata);
+ struct timeval timeval;
+ void (*callback)(struct pa_mainloop_api*a, struct pa_time_event *e, const struct timeval*tv, void *userdata);
void *userdata;
+ void (*destroy_callback) (struct pa_mainloop_api*a, struct pa_time_event *e, void *userdata);
};
-struct mainloop_source_time {
- struct mainloop_source_header header;
+struct pa_defer_event {
+ struct pa_mainloop *mainloop;
+ int dead;
int enabled;
-
- struct timeval timeval;
- void (*callback)(struct pa_mainloop_api*a, void *id, const struct timeval*tv, void *userdata);
+ void (*callback)(struct pa_mainloop_api*a, struct pa_defer_event*e, void *userdata);
void *userdata;
+ void (*destroy_callback) (struct pa_mainloop_api*a, struct pa_defer_event *e, void *userdata);
};
struct pa_mainloop {
- struct pa_idxset *io_sources, *fixed_sources, *idle_sources, *time_sources;
- int io_sources_scan_dead, fixed_sources_scan_dead, idle_sources_scan_dead, time_sources_scan_dead;
+ struct pa_idxset *io_events, *time_events, *defer_events;
+ int io_events_scan_dead, defer_events_scan_dead, time_events_scan_dead;
struct pollfd *pollfds;
unsigned max_pollfds, n_pollfds;
@@ -83,57 +83,248 @@ struct pa_mainloop {
struct pa_mainloop_api api;
};
-static void setup_api(struct pa_mainloop *m);
+/* IO events */
+static struct pa_io_event* mainloop_io_new(struct pa_mainloop_api*a, int fd, enum pa_io_event_flags events, void (*callback) (struct pa_mainloop_api*a, struct pa_io_event *e, int fd, enum pa_io_event_flags events, void *userdata), void *userdata) {
+ struct pa_mainloop *m;
+ struct pa_io_event *e;
+
+ assert(a && a->userdata && fd >= 0 && callback);
+ m = a->userdata;
+ assert(a == &m->api);
+
+ e = pa_xmalloc(sizeof(struct pa_io_event));
+ e->mainloop = m;
+ e->dead = 0;
+
+ e->fd = fd;
+ e->events = events;
+ e->callback = callback;
+ e->userdata = userdata;
+ e->destroy_callback = NULL;
+ e->pollfd = NULL;
+
+ pa_idxset_put(m->io_events, e, NULL);
+ m->rebuild_pollfds = 1;
+ return e;
+}
+
+static void mainloop_io_enable(struct pa_io_event *e, enum pa_io_event_flags events) {
+ assert(e && e->mainloop);
+
+ e->events = events;
+ if (e->pollfd)
+ e->pollfd->events =
+ (events & PA_IO_EVENT_INPUT ? POLLIN : 0) |
+ (events & PA_IO_EVENT_OUTPUT ? POLLOUT : 0) |
+ POLLHUP |
+ POLLERR;
+}
+
+static void mainloop_io_free(struct pa_io_event *e) {
+ assert(e && e->mainloop);
+ e->dead = e->mainloop->io_events_scan_dead = e->mainloop->rebuild_pollfds = 1;
+}
+
+static void mainloop_io_set_destroy(struct pa_io_event *e, void (*callback)(struct pa_mainloop_api*a, struct pa_io_event *e, void *userdata)) {
+ assert(e);
+ e->destroy_callback = callback;
+}
+
+/* Defer events */
+struct pa_defer_event* mainloop_defer_new(struct pa_mainloop_api*a, void (*callback) (struct pa_mainloop_api*a, struct pa_defer_event *e, void *userdata), void *userdata) {
+ struct pa_mainloop *m;
+ struct pa_defer_event *e;
+
+ assert(a && a->userdata && callback);
+ m = a->userdata;
+ assert(a == &m->api);
+
+ e = pa_xmalloc(sizeof(struct pa_defer_event));
+ e->mainloop = m;
+ e->dead = 0;
+
+ e->enabled = 1;
+ e->callback = callback;
+ e->userdata = userdata;
+ e->destroy_callback = NULL;
+
+ pa_idxset_put(m->defer_events, e, NULL);
+ return e;
+}
+
+static void mainloop_defer_enable(struct pa_defer_event *e, int b) {
+ assert(e);
+ e->enabled = b;
+}
+
+static void mainloop_defer_free(struct pa_defer_event *e) {
+ assert(e);
+ e->dead = e->mainloop->defer_events_scan_dead = 1;
+}
+
+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)) {
+ assert(e);
+ e->destroy_callback = callback;
+}
+
+/* Time events */
+static struct pa_time_event* mainloop_time_new(struct pa_mainloop_api*a, const struct timeval *tv, void (*callback) (struct pa_mainloop_api*a, struct pa_time_event*e, const struct timeval *tv, void *userdata), void *userdata) {
+ struct pa_mainloop *m;
+ struct pa_time_event *e;
+
+ assert(a && a->userdata && callback);
+ m = a->userdata;
+ assert(a == &m->api);
+
+ e = pa_xmalloc(sizeof(struct pa_time_event));
+ e->mainloop = m;
+ e->dead = 0;
+
+ e->enabled = !!tv;
+ if (tv)
+ e->timeval = *tv;
+
+ e->callback = callback;
+ e->userdata = userdata;
+ e->destroy_callback = NULL;
+
+ pa_idxset_put(m->time_events, e, NULL);
+ return e;
+}
+
+static void mainloop_time_restart(struct pa_time_event *e, const struct timeval *tv) {
+ assert(e);
+
+ if (tv) {
+ e->enabled = 1;
+ e->timeval = *tv;
+ } else
+ e->enabled = 0;
+}
+
+static void mainloop_time_free(struct pa_time_event *e) {
+ assert(e);
+ e->dead = e->mainloop->time_events_scan_dead = 1;
+}
+
+static void mainloop_time_set_destroy(struct pa_time_event *e, void (*callback)(struct pa_mainloop_api*a, struct pa_time_event *e, void *userdata)) {
+ assert(e);
+ e->destroy_callback = callback;
+}
+
+/* quit() */
+
+static void mainloop_quit(struct pa_mainloop_api*a, int retval) {
+ struct pa_mainloop *m;
+ assert(a && a->userdata);
+ m = a->userdata;
+ assert(a == &m->api);
+
+ m->quit = 1;
+ m->retval = retval;
+}
+
+static const struct 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,
+
+ time_new : mainloop_time_new,
+ time_restart : mainloop_time_restart,
+ time_free : mainloop_time_free,
+ time_set_destroy : mainloop_time_set_destroy,
+
+ defer_new : mainloop_defer_new,
+ defer_enable : mainloop_defer_enable,
+ defer_free : mainloop_defer_free,
+ defer_set_destroy : mainloop_defer_set_destroy,
+
+ quit : mainloop_quit,
+};
struct pa_mainloop *pa_mainloop_new(void) {
struct pa_mainloop *m;
m = pa_xmalloc(sizeof(struct pa_mainloop));
- m->io_sources = pa_idxset_new(NULL, NULL);
- m->fixed_sources = pa_idxset_new(NULL, NULL);
- m->idle_sources = pa_idxset_new(NULL, NULL);
- m->time_sources = pa_idxset_new(NULL, NULL);
+ m->io_events = pa_idxset_new(NULL, NULL);
+ m->defer_events = pa_idxset_new(NULL, NULL);
+ m->time_events = pa_idxset_new(NULL, NULL);
- assert(m->io_sources && m->fixed_sources && m->idle_sources && m->time_sources);
+ assert(m->io_events && m->defer_events && m->time_events);
- m->io_sources_scan_dead = m->fixed_sources_scan_dead = m->idle_sources_scan_dead = m->time_sources_scan_dead = 0;
+ m->io_events_scan_dead = m->defer_events_scan_dead = m->time_events_scan_dead = 0;
m->pollfds = NULL;
m->max_pollfds = m->n_pollfds = m->rebuild_pollfds = 0;
m->quit = m->running = m->retval = 0;
- setup_api(m);
+ m->api = vtable;
+ m->api.userdata = m;
return m;
}
-static int foreach(void *p, uint32_t index, int *del, void*userdata) {
- struct mainloop_source_header *h = p;
+static int io_foreach(void *p, uint32_t index, int *del, void*userdata) {
+ struct pa_io_event *e = p;
int *all = userdata;
- assert(p && del && all);
+ assert(e && del && all);
- if (*all || h->dead) {
- pa_xfree(h);
- *del = 1;
- }
+ if (!*all || !e->dead)
+ return 0;
+
+ if (e->destroy_callback)
+ e->destroy_callback(&e->mainloop->api, e, e->userdata);
+ pa_xfree(e);
+ *del = 1;
+ return 0;
+};
+static int time_foreach(void *p, uint32_t index, int *del, void*userdata) {
+ struct pa_time_event *e = p;
+ int *all = userdata;
+ assert(e && del && all);
+
+ if (!*all || !e->dead)
+ return 0;
+
+ if (e->destroy_callback)
+ e->destroy_callback(&e->mainloop->api, e, e->userdata);
+ pa_xfree(e);
+ *del = 1;
+ return 0;
+};
+
+static int defer_foreach(void *p, uint32_t index, int *del, void*userdata) {
+ struct pa_defer_event *e = p;
+ int *all = userdata;
+ assert(e && del && all);
+
+ if (!*all || !e->dead)
+ return 0;
+
+ if (e->destroy_callback)
+ e->destroy_callback(&e->mainloop->api, e, e->userdata);
+ pa_xfree(e);
+ *del = 1;
return 0;
};
void pa_mainloop_free(struct pa_mainloop* m) {
int all = 1;
assert(m);
- pa_idxset_foreach(m->io_sources, foreach, &all);
- pa_idxset_foreach(m->fixed_sources, foreach, &all);
- pa_idxset_foreach(m->idle_sources, foreach, &all);
- pa_idxset_foreach(m->time_sources, foreach, &all);
- pa_idxset_free(m->io_sources, NULL, NULL);
- pa_idxset_free(m->fixed_sources, NULL, NULL);
- pa_idxset_free(m->idle_sources, NULL, NULL);
- pa_idxset_free(m->time_sources, NULL, NULL);
+ pa_idxset_foreach(m->io_events, io_foreach, &all);
+ pa_idxset_foreach(m->time_events, time_foreach, &all);
+ pa_idxset_foreach(m->defer_events, defer_foreach, &all);
+
+ pa_idxset_free(m->io_events, NULL, NULL);
+ pa_idxset_free(m->time_events, NULL, NULL);
+ pa_idxset_free(m->defer_events, NULL, NULL);
pa_xfree(m->pollfds);
pa_xfree(m);
@@ -142,23 +333,21 @@ void pa_mainloop_free(struct pa_mainloop* m) {
static void scan_dead(struct pa_mainloop *m) {
int all = 0;
assert(m);
- if (m->io_sources_scan_dead)
- pa_idxset_foreach(m->io_sources, foreach, &all);
- if (m->fixed_sources_scan_dead)
- pa_idxset_foreach(m->fixed_sources, foreach, &all);
- if (m->idle_sources_scan_dead)
- pa_idxset_foreach(m->idle_sources, foreach, &all);
- if (m->time_sources_scan_dead)
- pa_idxset_foreach(m->time_sources, foreach, &all);
+ if (m->io_events_scan_dead)
+ pa_idxset_foreach(m->io_events, io_foreach, &all);
+ if (m->time_events_scan_dead)
+ pa_idxset_foreach(m->time_events, time_foreach, &all);
+ if (m->defer_events_scan_dead)
+ pa_idxset_foreach(m->defer_events, defer_foreach, &all);
}
static void rebuild_pollfds(struct pa_mainloop *m) {
- struct mainloop_source_io*s;
+ struct pa_io_event*e;
struct pollfd *p;
uint32_t index = PA_IDXSET_INVALID;
unsigned l;
- l = pa_idxset_ncontents(m->io_sources);
+ l = pa_idxset_ncontents(m->io_events);
if (m->max_pollfds < l) {
m->pollfds = pa_xrealloc(m->pollfds, sizeof(struct pollfd)*l);
m->max_pollfds = l;
@@ -166,15 +355,19 @@ static void rebuild_pollfds(struct pa_mainloop *m) {
m->n_pollfds = 0;
p = m->pollfds;
- for (s = pa_idxset_first(m->io_sources, &index); s; s = pa_idxset_next(m->io_sources, &index)) {
- if (s->header.dead) {
- s->pollfd = NULL;
+ for (e = pa_idxset_first(m->io_events, &index); e; e = pa_idxset_next(m->io_events, &index)) {
+ if (e->dead) {
+ e->pollfd = NULL;
continue;
}
- s->pollfd = p;
- p->fd = s->fd;
- p->events = ((s->events & PA_MAINLOOP_API_IO_EVENT_INPUT) ? POLLIN : 0) | ((s->events & PA_MAINLOOP_API_IO_EVENT_OUTPUT) ? POLLOUT : 0);
+ e->pollfd = p;
+ p->fd = e->fd;
+ p->events =
+ ((e->events & PA_IO_EVENT_INPUT) ? POLLIN : 0) |
+ ((e->events & PA_IO_EVENT_OUTPUT) ? POLLOUT : 0) |
+ POLLHUP |
+ POLLERR;
p->revents = 0;
p++;
@@ -184,60 +377,62 @@ static void rebuild_pollfds(struct pa_mainloop *m) {
static void dispatch_pollfds(struct pa_mainloop *m) {
uint32_t index = PA_IDXSET_INVALID;
- struct mainloop_source_io *s;
+ struct pa_io_event *e;
- for (s = pa_idxset_first(m->io_sources, &index); s; s = pa_idxset_next(m->io_sources, &index)) {
- if (s->header.dead || !s->pollfd || !s->pollfd->revents)
+ for (e = pa_idxset_first(m->io_events, &index); e; e = pa_idxset_next(m->io_events, &index)) {
+ if (e->dead || !e->pollfd || !e->pollfd->revents)
continue;
- assert(s->pollfd->fd == s->fd && s->callback);
- s->callback(&m->api, s, s->fd,
- ((s->pollfd->revents & POLLHUP) ? PA_MAINLOOP_API_IO_EVENT_HUP : 0) |
- ((s->pollfd->revents & POLLIN) ? PA_MAINLOOP_API_IO_EVENT_INPUT : 0) |
- ((s->pollfd->revents & POLLOUT) ? PA_MAINLOOP_API_IO_EVENT_OUTPUT : 0), s->userdata);
- s->pollfd->revents = 0;
+ assert(e->pollfd->fd == e->fd && e->callback);
+ e->callback(&m->api, e, e->fd,
+ (e->pollfd->revents & POLLHUP ? PA_IO_EVENT_HANGUP : 0) |
+ (e->pollfd->revents & POLLIN ? PA_IO_EVENT_INPUT : 0) |
+ (e->pollfd->revents & POLLOUT ? PA_IO_EVENT_OUTPUT : 0) |
+ (e->pollfd->revents & POLLERR ? PA_IO_EVENT_ERROR : 0),
+ e->userdata);
+ e->pollfd->revents = 0;
}
}
-static void run_fixed_or_idle(struct pa_mainloop *m, struct pa_idxset *i) {
- uint32_t index = PA_IDXSET_INVALID;
- struct mainloop_source_fixed_or_idle *s;
+static void dispatch_defer(struct pa_mainloop *m) {
+ uint32_t index;
+ struct pa_defer_event *e;
- for (s = pa_idxset_first(i, &index); s; s = pa_idxset_next(i, &index)) {
- if (s->header.dead || !s->enabled)
+ for (e = pa_idxset_first(m->defer_events, &index); e; e = pa_idxset_next(m->defer_events, &index)) {
+ if (e->dead || !e->enabled)
continue;
- assert(s->callback);
- s->callback(&m->api, s, s->userdata);
+ assert(e->callback);
+ e->callback(&m->api, e, e->userdata);
}
}
static int calc_next_timeout(struct pa_mainloop *m) {
- uint32_t index = PA_IDXSET_INVALID;
- struct mainloop_source_time *s;
+ uint32_t index;
+ struct pa_time_event *e;
struct timeval now;
int t = -1;
- if (pa_idxset_isempty(m->time_sources))
+ if (pa_idxset_isempty(m->time_events))
return -1;
gettimeofday(&now, NULL);
- for (s = pa_idxset_first(m->time_sources, &index); s; s = pa_idxset_next(m->time_sources, &index)) {
+ for (e = pa_idxset_first(m->time_events, &index); e; e = pa_idxset_next(m->time_events, &index)) {
int tmp;
- if (s->header.dead || !s->enabled)
+ if (e->dead || !e->enabled)
continue;
- if (s->timeval.tv_sec < now.tv_sec || (s->timeval.tv_sec == now.tv_sec && s->timeval.tv_usec <= now.tv_usec))
+ if (e->timeval.tv_sec < now.tv_sec || (e->timeval.tv_sec == now.tv_sec && e->timeval.tv_usec <= now.tv_usec))
return 0;
- tmp = (s->timeval.tv_sec - now.tv_sec)*1000;
+ tmp = (e->timeval.tv_sec - now.tv_sec)*1000;
- if (s->timeval.tv_usec > now.tv_usec)
- tmp += (s->timeval.tv_usec - now.tv_usec)/1000;
+ if (e->timeval.tv_usec > now.tv_usec)
+ tmp += (e->timeval.tv_usec - now.tv_usec)/1000;
else
- tmp -= (now.tv_usec - s->timeval.tv_usec)/1000;
+ tmp -= (now.tv_usec - e->timeval.tv_usec)/1000;
if (tmp == 0)
return 0;
@@ -249,43 +444,31 @@ static int calc_next_timeout(struct pa_mainloop *m) {
}
static void dispatch_timeout(struct pa_mainloop *m) {
- uint32_t index = PA_IDXSET_INVALID;
- struct mainloop_source_time *s;
+ uint32_t index;
+ struct pa_time_event *e;
struct timeval now;
assert(m);
- if (pa_idxset_isempty(m->time_sources))
+ if (pa_idxset_isempty(m->time_events))
return;
gettimeofday(&now, NULL);
- for (s = pa_idxset_first(m->time_sources, &index); s; s = pa_idxset_next(m->time_sources, &index)) {
+ for (e = pa_idxset_first(m->time_events, &index); e; e = pa_idxset_next(m->time_events, &index)) {
- if (s->header.dead || !s->enabled)
+ if (e->dead || !e->enabled)
continue;
- if (s->timeval.tv_sec < now.tv_sec || (s->timeval.tv_sec == now.tv_sec && s->timeval.tv_usec <= now.tv_usec)) {
- assert(s->callback);
+ if (e->timeval.tv_sec < now.tv_sec || (e->timeval.tv_sec == now.tv_sec && e->timeval.tv_usec <= now.tv_usec)) {
+ assert(e->callback);
- s->enabled = 0;
- s->callback(&m->api, s, &s->timeval, s->userdata);
+ e->enabled = 0;
+ e->callback(&m->api, e, &e->timeval, e->userdata);
}
}
}
-static int any_idle_sources(struct pa_mainloop *m) {
- struct mainloop_source_fixed_or_idle *s;
- uint32_t index;
- assert(m);
-
- for (s = pa_idxset_first(m->idle_sources, &index); s; s = pa_idxset_next(m->idle_sources, &index))
- if (!s->header.dead && s->enabled)
- return 1;
-
- return 0;
-}
-
int pa_mainloop_iterate(struct pa_mainloop *m, int block, int *retval) {
- int r, idle;
+ int r;
assert(m && !m->running);
if(m->quit) {
@@ -297,23 +480,16 @@ int pa_mainloop_iterate(struct pa_mainloop *m, int block, int *retval) {
m->running = 1;
scan_dead(m);
- run_fixed_or_idle(m, m->fixed_sources);
+ dispatch_defer(m);
if (m->rebuild_pollfds) {
rebuild_pollfds(m);
m->rebuild_pollfds = 0;
}
- idle = any_idle_sources(m);
-
do {
- int t;
-
- if (!block || idle)
- t = 0;
- else
- t = calc_next_timeout(m);
-
+ int t = block ? calc_next_timeout(m) : 0;
+ /*fprintf(stderr, "%u\n", t);*/
r = poll(m->pollfds, m->n_pollfds, t);
} while (r < 0 && errno == EINTR);
@@ -321,8 +497,6 @@ int pa_mainloop_iterate(struct pa_mainloop *m, int block, int *retval) {
if (r > 0)
dispatch_pollfds(m);
- else if (r == 0 && idle)
- run_fixed_or_idle(m, m->idle_sources);
else if (r < 0)
fprintf(stderr, "select(): %s\n", strerror(errno));
@@ -341,209 +515,7 @@ void pa_mainloop_quit(struct pa_mainloop *m, int r) {
m->quit = r;
}
-/* IO sources */
-static void* mainloop_source_io(struct pa_mainloop_api*a, int fd, enum pa_mainloop_api_io_events events, void (*callback) (struct pa_mainloop_api*a, void *id, int fd, enum pa_mainloop_api_io_events events, void *userdata), void *userdata) {
- struct pa_mainloop *m;
- struct mainloop_source_io *s;
- assert(a && a->userdata && fd >= 0 && callback);
- m = a->userdata;
- assert(a == &m->api);
-
- s = pa_xmalloc(sizeof(struct mainloop_source_io));
- s->header.mainloop = m;
- s->header.dead = 0;
-
- s->fd = fd;
- s->events = events;
- s->callback = callback;
- s->userdata = userdata;
- s->pollfd = NULL;
-
- pa_idxset_put(m->io_sources, s, NULL);
- m->rebuild_pollfds = 1;
- return s;
-}
-
-static void mainloop_enable_io(struct pa_mainloop_api*a, void* id, enum pa_mainloop_api_io_events events) {
- struct pa_mainloop *m;
- struct mainloop_source_io *s = id;
- assert(a && a->userdata && s && !s->header.dead);
- m = a->userdata;
- assert(a == &m->api && s->header.mainloop == m);
-
- s->events = events;
- if (s->pollfd)
- s->pollfd->events = ((s->events & PA_MAINLOOP_API_IO_EVENT_INPUT) ? POLLIN : 0) | ((s->events & PA_MAINLOOP_API_IO_EVENT_OUTPUT) ? POLLOUT : 0);
-}
-
-static void mainloop_cancel_io(struct pa_mainloop_api*a, void* id) {
- struct pa_mainloop *m;
- struct mainloop_source_io *s = id;
- assert(a && a->userdata && s && !s->header.dead);
- m = a->userdata;
- assert(a == &m->api && s->header.mainloop == m);
-
- s->header.dead = 1;
- m->io_sources_scan_dead = 1;
- m->rebuild_pollfds = 1;
-}
-
-/* Fixed sources */
-static void* mainloop_source_fixed(struct pa_mainloop_api*a, void (*callback) (struct pa_mainloop_api*a, void *id, void *userdata), void *userdata) {
- struct pa_mainloop *m;
- struct mainloop_source_fixed_or_idle *s;
- assert(a && a->userdata && callback);
- m = a->userdata;
- assert(a == &m->api);
-
- s = pa_xmalloc(sizeof(struct mainloop_source_fixed_or_idle));
- s->header.mainloop = m;
- s->header.dead = 0;
-
- s->enabled = 1;
- s->callback = callback;
- s->userdata = userdata;
-
- pa_idxset_put(m->fixed_sources, s, NULL);
- return s;
-}
-
-static void mainloop_enable_fixed(struct pa_mainloop_api*a, void* id, int b) {
- struct pa_mainloop *m;
- struct mainloop_source_fixed_or_idle *s = id;
- assert(a && a->userdata && s && !s->header.dead);
- m = a->userdata;
- assert(a == &m->api);
-
- s->enabled = b;
-}
-
-static void mainloop_cancel_fixed(struct pa_mainloop_api*a, void* id) {
- struct pa_mainloop *m;
- struct mainloop_source_fixed_or_idle *s = id;
- assert(a && a->userdata && s && !s->header.dead);
- m = a->userdata;
- assert(a == &m->api);
-
- s->header.dead = 1;
- m->fixed_sources_scan_dead = 1;
-}
-
-/* Idle sources */
-static void* mainloop_source_idle(struct pa_mainloop_api*a, void (*callback) (struct pa_mainloop_api*a, void *id, void *userdata), void *userdata) {
- struct pa_mainloop *m;
- struct mainloop_source_fixed_or_idle *s;
- assert(a && a->userdata && callback);
- m = a->userdata;
- assert(a == &m->api);
-
- s = pa_xmalloc(sizeof(struct mainloop_source_fixed_or_idle));
- s->header.mainloop = m;
- s->header.dead = 0;
-
- s->enabled = 1;
- s->callback = callback;
- s->userdata = userdata;
-
- pa_idxset_put(m->idle_sources, s, NULL);
- return s;
-}
-
-static void mainloop_cancel_idle(struct pa_mainloop_api*a, void* id) {
- struct pa_mainloop *m;
- struct mainloop_source_fixed_or_idle *s = id;
- assert(a && a->userdata && s && !s->header.dead);
- m = a->userdata;
- assert(a == &m->api);
-
- s->header.dead = 1;
- m->idle_sources_scan_dead = 1;
-}
-
-/* Time sources */
-static void* mainloop_source_time(struct pa_mainloop_api*a, const struct timeval *tv, void (*callback) (struct pa_mainloop_api*a, void *id, const struct timeval *tv, void *userdata), void *userdata) {
- struct pa_mainloop *m;
- struct mainloop_source_time *s;
- assert(a && a->userdata && callback);
- m = a->userdata;
- assert(a == &m->api);
-
- s = pa_xmalloc(sizeof(struct mainloop_source_time));
- s->header.mainloop = m;
- s->header.dead = 0;
-
- s->enabled = !!tv;
- if (tv)
- s->timeval = *tv;
-
- s->callback = callback;
- s->userdata = userdata;
-
- pa_idxset_put(m->time_sources, s, NULL);
- return s;
-}
-
-static void mainloop_enable_time(struct pa_mainloop_api*a, void *id, const struct timeval *tv) {
- struct pa_mainloop *m;
- struct mainloop_source_time *s = id;
- assert(a && a->userdata && s && !s->header.dead);
- m = a->userdata;
- assert(a == &m->api);
-
- if (tv) {
- s->enabled = 1;
- s->timeval = *tv;
- } else
- s->enabled = 0;
-}
-
-static void mainloop_cancel_time(struct pa_mainloop_api*a, void* id) {
- struct pa_mainloop *m;
- struct mainloop_source_time *s = id;
- assert(a && a->userdata && s && !s->header.dead);
- m = a->userdata;
- assert(a == &m->api);
-
- s->header.dead = 1;
- m->time_sources_scan_dead = 1;
-
-}
-
-static void mainloop_quit(struct pa_mainloop_api*a, int retval) {
- struct pa_mainloop *m;
- assert(a && a->userdata);
- m = a->userdata;
- assert(a == &m->api);
-
- m->quit = 1;
- m->retval = retval;
-}
-
-static void setup_api(struct pa_mainloop *m) {
- assert(m);
-
- m->api.userdata = m;
- m->api.source_io = mainloop_source_io;
- m->api.enable_io = mainloop_enable_io;
- m->api.cancel_io = mainloop_cancel_io;
-
- m->api.source_fixed = mainloop_source_fixed;
- m->api.enable_fixed = mainloop_enable_fixed;
- m->api.cancel_fixed = mainloop_cancel_fixed;
-
- m->api.source_idle = mainloop_source_idle;
- m->api.enable_idle = mainloop_enable_fixed; /* (!) */
- m->api.cancel_idle = mainloop_cancel_idle;
-
- m->api.source_time = mainloop_source_time;
- m->api.enable_time = mainloop_enable_time;
- m->api.cancel_time = mainloop_cancel_time;
-
- m->api.quit = mainloop_quit;
-}
-
struct pa_mainloop_api* pa_mainloop_get_api(struct pa_mainloop*m) {
assert(m);
return &m->api;
}
-
diff --git a/polyp/module-alsa-sink.c b/polyp/module-alsa-sink.c
index a0fa52db..5b4a7b73 100644
--- a/polyp/module-alsa-sink.c
+++ b/polyp/module-alsa-sink.c
@@ -42,8 +42,8 @@
struct userdata {
snd_pcm_t *pcm_handle;
struct pa_sink *sink;
- void **io_sources;
- unsigned n_io_sources;
+ struct pa_io_event **io_events;
+ unsigned n_io_events;
size_t frame_size, fragment_size;
struct pa_memchunk memchunk, silence;
@@ -128,9 +128,9 @@ static void do_write(struct userdata *u) {
}
}
-static void io_callback(struct pa_mainloop_api*a, void *id, int fd, enum pa_mainloop_api_io_events events, void *userdata) {
+static void io_callback(struct pa_mainloop_api*a, struct pa_io_event *e, int fd, enum pa_io_event_flags f, void *userdata) {
struct userdata *u = userdata;
- assert(u && a && id);
+ assert(u && a && e);
if (snd_pcm_state(u->pcm_handle) == SND_PCM_STATE_XRUN)
xrun_recovery(u);
@@ -207,7 +207,7 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) {
pa_sink_set_owner(u->sink, m);
u->sink->description = pa_sprintf_malloc("Advanced Linux Sound Architecture PCM on '%s'", dev);
- if (pa_create_io_sources(u->pcm_handle, c->mainloop, &u->io_sources, &u->n_io_sources, io_callback, u) < 0) {
+ if (pa_create_io_events(u->pcm_handle, c->mainloop, &u->io_events, &u->n_io_events, io_callback, u) < 0) {
fprintf(stderr, __FILE__": failed to obtain file descriptors\n");
goto fail;
}
@@ -251,8 +251,8 @@ void pa_module_done(struct pa_core *c, struct pa_module*m) {
if (u->sink)
pa_sink_free(u->sink);
- if (u->io_sources)
- pa_free_io_sources(c->mainloop, u->io_sources, u->n_io_sources);
+ if (u->io_events)
+ pa_free_io_events(c->mainloop, u->io_events, u->n_io_events);
if (u->pcm_handle) {
snd_pcm_drop(u->pcm_handle);
diff --git a/polyp/module-alsa-source.c b/polyp/module-alsa-source.c
index 8207d462..df716f73 100644
--- a/polyp/module-alsa-source.c
+++ b/polyp/module-alsa-source.c
@@ -42,8 +42,8 @@
struct userdata {
snd_pcm_t *pcm_handle;
struct pa_source *source;
- void **io_sources;
- unsigned n_io_sources;
+ struct pa_io_event **io_events;
+ unsigned n_io_events;
size_t frame_size, fragment_size;
struct pa_memchunk memchunk;
@@ -128,9 +128,9 @@ static void do_read(struct userdata *u) {
}
}
-static void io_callback(struct pa_mainloop_api*a, void *id, int fd, enum pa_mainloop_api_io_events events, void *userdata) {
+static void io_callback(struct pa_mainloop_api*a, struct pa_io_event *e, int fd, enum pa_io_event_flags f, void *userdata) {
struct userdata *u = userdata;
- assert(u && a && id);
+ assert(u && a && e);
if (snd_pcm_state(u->pcm_handle) == SND_PCM_STATE_XRUN)
xrun_recovery(u);
@@ -189,7 +189,7 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) {
pa_source_set_owner(u->source, m);
u->source->description = pa_sprintf_malloc("Advanced Linux Sound Architecture PCM on '%s'", dev);
- if (pa_create_io_sources(u->pcm_handle, c->mainloop, &u->io_sources, &u->n_io_sources, io_callback, u) < 0) {
+ if (pa_create_io_events(u->pcm_handle, c->mainloop, &u->io_events, &u->n_io_events, io_callback, u) < 0) {
fprintf(stderr, __FILE__": failed to obtain file descriptors\n");
goto fail;
}
@@ -230,8 +230,8 @@ void pa_module_done(struct pa_core *c, struct pa_module*m) {
if (u->source)
pa_source_free(u->source);
- if (u->io_sources)
- pa_free_io_sources(c->mainloop, u->io_sources, u->n_io_sources);
+ if (u->io_events)
+ pa_free_io_events(c->mainloop, u->io_events, u->n_io_events);
if (u->pcm_handle) {
snd_pcm_drop(u->pcm_handle);
diff --git a/polyp/module-oss-mmap.c b/polyp/module-oss-mmap.c
index 37710fc5..ea768a98 100644
--- a/polyp/module-oss-mmap.c
+++ b/polyp/module-oss-mmap.c
@@ -59,7 +59,7 @@ struct userdata {
void *in_mmap, *out_mmap;
size_t in_mmap_length, out_mmap_length;
- void *mainloop_source;
+ struct pa_io_event *io_event;
struct pa_memblock **in_memblocks, **out_memblocks;
unsigned out_current, in_current;
@@ -195,14 +195,13 @@ static void do_read(struct userdata *u) {
in_clear_memblocks(u, u->in_fragments/2);
};
-static void io_callback(struct pa_mainloop_api *m, void *id, int fd, enum pa_mainloop_api_io_events events, void *userdata) {
+static void io_callback(struct pa_mainloop_api *m, struct pa_io_event *e, int fd, enum pa_io_event_flags f, void *userdata) {
struct userdata *u = userdata;
+ assert (u && u->core->mainloop == m && u->io_event == e);
- assert (u && u->core->mainloop == m && u->mainloop_source == id);
-
- if (events & PA_MAINLOOP_API_IO_EVENT_INPUT)
+ if (f & PA_IO_EVENT_INPUT)
do_read(u);
- if (events & PA_MAINLOOP_API_IO_EVENT_OUTPUT)
+ if (f & PA_IO_EVENT_OUTPUT)
do_write(u);
}
@@ -352,8 +351,8 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) {
assert(u->source || u->sink);
- u->mainloop_source = c->mainloop->source_io(c->mainloop, u->fd, (u->source ? PA_MAINLOOP_API_IO_EVENT_INPUT : 0) | (u->sink ? PA_MAINLOOP_API_IO_EVENT_OUTPUT : 0), io_callback, u);
- assert(u->mainloop_source);
+ u->io_event = c->mainloop->io_new(c->mainloop, u->fd, (u->source ? PA_IO_EVENT_INPUT : 0) | (u->sink ? PA_IO_EVENT_OUTPUT : 0), io_callback, u);
+ assert(u->io_event);
pa_modargs_free(ma);
@@ -403,8 +402,8 @@ void pa_module_done(struct pa_core *c, struct pa_module*m) {
if (u->source)
pa_source_free(u->source);
- if (u->mainloop_source)
- u->core->mainloop->cancel_io(u->core->mainloop, u->mainloop_source);
+ if (u->io_event)
+ u->core->mainloop->io_free(u->io_event);
if (u->fd >= 0)
close(u->fd);
diff --git a/polyp/module-pipe-sink.c b/polyp/module-pipe-sink.c
index dc2bc633..22d9f676 100644
--- a/polyp/module-pipe-sink.c
+++ b/polyp/module-pipe-sink.c
@@ -50,7 +50,7 @@ struct userdata {
struct pa_sink *sink;
struct pa_iochannel *io;
- void *mainloop_source;
+ struct pa_defer_event *defer_event;
struct pa_memchunk memchunk;
struct pa_module *module;
@@ -69,7 +69,7 @@ static void do_write(struct userdata *u) {
ssize_t r;
assert(u);
- u->core->mainloop->enable_fixed(u->core->mainloop, u->mainloop_source, 0);
+ u->core->mainloop->defer_enable(u->defer_event, 0);
if (!pa_iochannel_is_writable(u->io))
return;
@@ -101,10 +101,10 @@ static void notify_cb(struct pa_sink*s) {
assert(s && u);
if (pa_iochannel_is_writable(u->io))
- u->core->mainloop->enable_fixed(u->core->mainloop, u->mainloop_source, 1);
+ u->core->mainloop->defer_enable(u->defer_event, 1);
}
-static void fixed_callback(struct pa_mainloop_api *m, void *id, void *userdata) {
+static void defer_callback(struct pa_mainloop_api *m, struct pa_defer_event*e, void *userdata) {
struct userdata *u = userdata;
assert(u);
do_write(u);
@@ -175,9 +175,9 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) {
u->memchunk.memblock = NULL;
u->memchunk.length = 0;
- u->mainloop_source = c->mainloop->source_fixed(c->mainloop, fixed_callback, u);
- assert(u->mainloop_source);
- c->mainloop->enable_fixed(c->mainloop, u->mainloop_source, 0);
+ u->defer_event = c->mainloop->defer_new(c->mainloop, defer_callback, u);
+ assert(u->defer_event);
+ c->mainloop->defer_enable(u->defer_event, 0);
u->module = m;
m->userdata = u;
@@ -210,7 +210,7 @@ void pa_module_done(struct pa_core *c, struct pa_module*m) {
pa_sink_free(u->sink);
pa_iochannel_free(u->io);
- u->core->mainloop->cancel_fixed(u->core->mainloop, u->mainloop_source);
+ u->core->mainloop->defer_free(u->defer_event);
assert(u->filename);
unlink(u->filename);
diff --git a/polyp/module-x11-bell.c b/polyp/module-x11-bell.c
index 2cf76099..5449e944 100644
--- a/polyp/module-x11-bell.c
+++ b/polyp/module-x11-bell.c
@@ -14,7 +14,7 @@
#include "namereg.h"
struct x11_source {
- void *io_source;
+ struct pa_io_event *io_event;
struct x11_source *next;
};
@@ -52,7 +52,7 @@ static int ring_bell(struct userdata *u, int percent) {
return 0;
}
-static void io_callback(struct pa_mainloop_api*a, void *id, int fd, enum pa_mainloop_api_io_events events, void *userdata) {
+static void io_callback(struct pa_mainloop_api*a, struct pa_io_event *e, int fd, enum pa_io_event_flags f, void *userdata) {
struct userdata *u = userdata;
assert(u);
@@ -77,8 +77,8 @@ static void new_io_source(struct userdata *u, int fd) {
struct x11_source *s;
s = pa_xmalloc(sizeof(struct x11_source));
- s->io_source = u->core->mainloop->source_io(u->core->mainloop, fd, PA_MAINLOOP_API_IO_EVENT_INPUT, io_callback, u);
- assert(s->io_source);
+ s->io_event = u->core->mainloop->io_new(u->core->mainloop, fd, PA_IO_EVENT_INPUT, io_callback, u);
+ assert(s->io_event);
s->next = u->x11_sources;
u->x11_sources = s;
}
@@ -149,7 +149,7 @@ void pa_module_done(struct pa_core *c, struct pa_module*m) {
while (u->x11_sources) {
struct x11_source *s = u->x11_sources;
u->x11_sources = u->x11_sources->next;
- c->mainloop->cancel_io(c->mainloop, s->io_source);
+ c->mainloop->io_free(s->io_event);
pa_xfree(s);
}
diff --git a/polyp/module.c b/polyp/module.c
index 8c5e318f..83bfa800 100644
--- a/polyp/module.c
+++ b/polyp/module.c
@@ -35,16 +35,16 @@
#define UNLOAD_POLL_TIME 10
-static void timeout_callback(struct pa_mainloop_api *m, void *id, const struct timeval *tv, void *userdata) {
+static void timeout_callback(struct pa_mainloop_api *m, struct pa_time_event*e, const struct timeval *tv, void *userdata) {
struct pa_core *c = userdata;
struct timeval ntv;
- assert(c && c->mainloop == m && c->auto_unload_mainloop_source == id);
+ assert(c && c->mainloop == m && c->auto_unload_event == e);
pa_module_unload_unused(c);
gettimeofday(&ntv, NULL);
ntv.tv_sec += UNLOAD_POLL_TIME;
- m->enable_time(m, id, &ntv);
+ m->time_restart(e, &ntv);
}
struct pa_module* pa_module_load(struct pa_core *c, const char *name, const char *argument) {
@@ -79,13 +79,13 @@ struct pa_module* pa_module_load(struct pa_core *c, const char *name, const char
if (!c->modules)
c->modules = pa_idxset_new(NULL, NULL);
- if (!c->auto_unload_mainloop_source) {
+ if (!c->auto_unload_event) {
struct timeval ntv;
gettimeofday(&ntv, NULL);
ntv.tv_sec += UNLOAD_POLL_TIME;
- c->auto_unload_mainloop_source = c->mainloop->source_time(c->mainloop, &ntv, timeout_callback, c);
+ c->auto_unload_event = c->mainloop->time_new(c->mainloop, &ntv, timeout_callback, c);
}
- assert(c->auto_unload_mainloop_source);
+ assert(c->auto_unload_event);
assert(c->modules);
r = pa_idxset_put(c->modules, m, &m->index);
@@ -159,9 +159,9 @@ void pa_module_unload_all(struct pa_core *c) {
pa_idxset_free(c->modules, free_callback, NULL);
c->modules = NULL;
- if (c->auto_unload_mainloop_source)
- c->mainloop->cancel_time(c->mainloop, c->auto_unload_mainloop_source);
- c->auto_unload_mainloop_source = NULL;
+ if (c->auto_unload_event)
+ c->mainloop->time_free(c->auto_unload_event);
+ c->auto_unload_event = NULL;
}
static int unused_callback(void *p, uint32_t index, int *del, void *userdata) {
@@ -193,7 +193,7 @@ struct once_info {
uint32_t index;
};
-static void module_unload_once_callback(void *userdata) {
+static void module_unload_once_callback(struct pa_mainloop_api *m, void *userdata) {
struct once_info *i = userdata;
assert(i);
pa_module_unload_by_index(i->core, i->index);
diff --git a/polyp/module.h b/polyp/module.h
index de195a4b..acc08c3e 100644
--- a/polyp/module.h
+++ b/polyp/module.h
@@ -59,5 +59,4 @@ void pa_module_done(struct pa_core *c, struct pa_module*m);
void pa_module_set_used(struct pa_module*m, int used);
-
#endif
diff --git a/polyp/native-common.h b/polyp/native-common.h
index dc730e4b..d8a2a5ab 100644
--- a/polyp/native-common.h
+++ b/polyp/native-common.h
@@ -48,13 +48,15 @@ enum {
PA_COMMAND_PLAY_SAMPLE,
PA_COMMAND_REMOVE_SAMPLE,
- PA_COMMAND_GET_SINK,
- PA_COMMAND_GET_SOURCE,
- PA_COMMAND_GET_MODULE,
- PA_COMMAND_GET_CLIENT,
- PA_COMMAND_GET_SINK_INPUT,
- PA_COMMAND_GET_SOURCE_OUTPUT,
- PA_COMMAND_GET_SAMPLE,
+ PA_COMMAND_GET_SINK_INFO,
+ PA_COMMAND_GET_SINK_INFO_LIST,
+ PA_COMMAND_GET_SOURCE_INFO,
+ PA_COMMAND_GET_SOURCE_INFO_LIST,
+ PA_COMMAND_GET_MODULE_INFO,
+ PA_COMMAND_GET_CLIENT_INFO,
+ PA_COMMAND_GET_SINK_INPUT_INFO,
+ PA_COMMAND_GET_SOURCE_OUTPUT_INFO,
+ PA_COMMAND_GET_SAMPLE_INFO,
PA_COMMAND_SUBSCRIBE,
PA_COMMAND_SUBSCRIBE_EVENT,
diff --git a/polyp/pacat.c b/polyp/pacat.c
index 55a0f6b9..4d8605c7 100644
--- a/polyp/pacat.c
+++ b/polyp/pacat.c
@@ -45,7 +45,7 @@ static struct pa_mainloop_api *mainloop_api = NULL;
static void *buffer = NULL;
static size_t buffer_length = 0, buffer_index = 0;
-static void* stdio_source = NULL;
+static struct pa_io_event* stdio_event = NULL;
static void quit(int ret) {
assert(mainloop_api);
@@ -89,8 +89,8 @@ static void do_stream_write(size_t length) {
static void stream_write_callback(struct pa_stream *s, size_t length, void *userdata) {
assert(s && length);
- if (stdio_source)
- mainloop_api->enable_io(mainloop_api, stdio_source, PA_MAINLOOP_API_IO_EVENT_INPUT);
+ if (stdio_event)
+ mainloop_api->io_enable(stdio_event, PA_IO_EVENT_INPUT);
if (!buffer)
return;
@@ -101,8 +101,8 @@ static void stream_write_callback(struct pa_stream *s, size_t length, void *user
static void stream_read_callback(struct pa_stream *s, const void*data, size_t length, void *userdata) {
assert(s && data && length);
- if (stdio_source)
- mainloop_api->enable_io(mainloop_api, stdio_source, PA_MAINLOOP_API_IO_EVENT_OUTPUT);
+ if (stdio_event)
+ mainloop_api->io_enable(stdio_event, PA_IO_EVENT_OUTPUT);
if (buffer) {
fprintf(stderr, "Buffer overrrun, dropping incoming data\n");
@@ -174,13 +174,13 @@ static void stream_drain_complete(struct pa_stream*s, void *userdata) {
fprintf(stderr, "Draining connection to server.\n");
}
-static void stdin_callback(struct pa_mainloop_api*a, void *id, int fd, enum pa_mainloop_api_io_events events, void *userdata) {
+static void stdin_callback(struct pa_mainloop_api*a, struct pa_io_event *e, int fd, enum pa_io_event_flags f, void *userdata) {
size_t l, w = 0;
ssize_t r;
- assert(a == mainloop_api && id && stdio_source == id);
+ assert(a == mainloop_api && e && stdio_event == e);
if (buffer) {
- mainloop_api->enable_io(mainloop_api, stdio_source, PA_MAINLOOP_API_IO_EVENT_NULL);
+ mainloop_api->io_enable(stdio_event, PA_IO_EVENT_NULL);
return;
}
@@ -198,8 +198,8 @@ static void stdin_callback(struct pa_mainloop_api*a, void *id, int fd, enum pa_m
quit(1);
}
- mainloop_api->cancel_io(mainloop_api, stdio_source);
- stdio_source = NULL;
+ mainloop_api->io_free(stdio_event);
+ stdio_event = NULL;
return;
}
@@ -210,12 +210,12 @@ static void stdin_callback(struct pa_mainloop_api*a, void *id, int fd, enum pa_m
do_stream_write(w);
}
-static void stdout_callback(struct pa_mainloop_api*a, void *id, int fd, enum pa_mainloop_api_io_events events, void *userdata) {
+static void stdout_callback(struct pa_mainloop_api*a, struct pa_io_event *e, int fd, enum pa_io_event_flags f, void *userdata) {
ssize_t r;
- assert(a == mainloop_api && id && stdio_source == id);
+ assert(a == mainloop_api && e && stdio_event == e);
if (!buffer) {
- mainloop_api->enable_io(mainloop_api, stdio_source, PA_MAINLOOP_API_IO_EVENT_NULL);
+ mainloop_api->io_enable(stdio_event, PA_IO_EVENT_NULL);
return;
}
@@ -225,8 +225,8 @@ static void stdout_callback(struct pa_mainloop_api*a, void *id, int fd, enum pa_
fprintf(stderr, "write() failed: %s\n", strerror(errno));
quit(1);
- mainloop_api->cancel_io(mainloop_api, stdio_source);
- stdio_source = NULL;
+ mainloop_api->io_free(stdio_event);
+ stdio_event = NULL;
return;
}
@@ -240,7 +240,7 @@ static void stdout_callback(struct pa_mainloop_api*a, void *id, int fd, enum pa_
}
}
-static void exit_signal_callback(void *id, int sig, void *userdata) {
+static void exit_signal_callback(struct pa_mainloop_api*m, struct pa_signal_event *e, int sig, void *userdata) {
fprintf(stderr, "Got SIGINT, exiting.\n");
quit(0);
@@ -258,7 +258,7 @@ static void stream_get_latency_callback(struct pa_stream *s, uint32_t latency, v
fprintf(stderr, "Current latency is %u usecs.\n", latency);
}
-static void sigusr1_signal_callback(void *id, int sig, void *userdata) {
+static void sigusr1_signal_callback(struct pa_mainloop_api*m, struct pa_signal_event *e, int sig, void *userdata) {
if (mode == PLAYBACK) {
fprintf(stderr, "Got SIGUSR1, requesting latency.\n");
pa_stream_get_latency(stream, stream_get_latency_callback, NULL);
@@ -289,14 +289,14 @@ int main(int argc, char *argv[]) {
r = pa_signal_init(mainloop_api);
assert(r == 0);
- pa_signal_register(SIGINT, exit_signal_callback, NULL);
- pa_signal_register(SIGUSR1, sigusr1_signal_callback, NULL);
+ pa_signal_new(SIGINT, exit_signal_callback, NULL);
+ pa_signal_new(SIGUSR1, sigusr1_signal_callback, NULL);
signal(SIGPIPE, SIG_IGN);
- if (!(stdio_source = mainloop_api->source_io(mainloop_api,
- mode == PLAYBACK ? STDIN_FILENO : STDOUT_FILENO,
- mode == PLAYBACK ? PA_MAINLOOP_API_IO_EVENT_INPUT : PA_MAINLOOP_API_IO_EVENT_OUTPUT,
- mode == PLAYBACK ? stdin_callback : stdout_callback, NULL))) {
+ if (!(stdio_event = mainloop_api->io_new(mainloop_api,
+ mode == PLAYBACK ? STDIN_FILENO : STDOUT_FILENO,
+ mode == PLAYBACK ? PA_IO_EVENT_INPUT : PA_IO_EVENT_OUTPUT,
+ mode == PLAYBACK ? stdin_callback : stdout_callback, NULL))) {
fprintf(stderr, "source_io() failed.\n");
goto quit;
}
diff --git a/polyp/pactl.c b/polyp/pactl.c
index 28b187b0..2f3a4833 100644
--- a/polyp/pactl.c
+++ b/polyp/pactl.c
@@ -205,7 +205,7 @@ fail:
quit(1);
}
-static void exit_signal_callback(void *id, int sig, void *userdata) {
+static void exit_signal_callback(struct pa_mainloop_api *m, struct pa_signal_event *e, int sig, void *userdata) {
fprintf(stderr, "Got SIGINT, exiting.\n");
quit(0);
}
@@ -284,7 +284,7 @@ int main(int argc, char *argv[]) {
r = pa_signal_init(mainloop_api);
assert(r == 0);
- pa_signal_register(SIGINT, exit_signal_callback, NULL);
+ pa_signal_new(SIGINT, exit_signal_callback, NULL);
signal(SIGPIPE, SIG_IGN);
if (!(context = pa_context_new(mainloop_api, argv[0]))) {
diff --git a/polyp/pdispatch.c b/polyp/pdispatch.c
index c34c6e0a..2d4c4d64 100644
--- a/polyp/pdispatch.c
+++ b/polyp/pdispatch.c
@@ -69,7 +69,7 @@ struct reply_info {
void (*callback)(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata);
void *userdata;
uint32_t tag;
- void *mainloop_timeout;
+ struct pa_time_event *time_event;
int callback_is_running;
};
@@ -87,7 +87,7 @@ static void reply_info_free(struct reply_info *r) {
assert(r && r->pdispatch && r->pdispatch->mainloop);
if (r->pdispatch)
- r->pdispatch->mainloop->cancel_time(r->pdispatch->mainloop, r->mainloop_timeout);
+ r->pdispatch->mainloop->time_free(r->time_event);
if (r->previous)
r->previous->next = r->next;
@@ -191,9 +191,9 @@ finish:
return ret;
}
-static void timeout_callback(struct pa_mainloop_api*m, void *id, const struct timeval *tv, void *userdata) {
+static void timeout_callback(struct pa_mainloop_api*m, struct pa_time_event*e, const struct timeval *tv, void *userdata) {
struct reply_info*r = userdata;
- assert (r && r->mainloop_timeout == id && r->pdispatch && r->pdispatch->mainloop == m && r->callback);
+ assert (r && r->time_event == e && r->pdispatch && r->pdispatch->mainloop == m && r->callback);
r->callback(r->pdispatch, PA_COMMAND_TIMEOUT, r->tag, NULL, r->userdata);
reply_info_free(r);
@@ -217,8 +217,8 @@ void pa_pdispatch_register_reply(struct pa_pdispatch *pd, uint32_t tag, int time
gettimeofday(&tv, NULL);
tv.tv_sec += timeout;
- r->mainloop_timeout = pd->mainloop->source_time(pd->mainloop, &tv, timeout_callback, r);
- assert(r->mainloop_timeout);
+ r->time_event = pd->mainloop->time_new(pd->mainloop, &tv, timeout_callback, r);
+ assert(r->time_event);
r->previous = NULL;
r->next = pd->replies;
diff --git a/polyp/play-memchunk.c b/polyp/play-memchunk.c
index 5c448a75..86634407 100644
--- a/polyp/play-memchunk.c
+++ b/polyp/play-memchunk.c
@@ -30,7 +30,7 @@ static int sink_input_peek(struct pa_sink_input *i, struct pa_memchunk *chunk) {
return 0;
}
-static void si_kill(void *i) {
+static void si_kill(struct pa_mainloop_api *m, void *i) {
sink_input_kill(i);
}
diff --git a/polyp/polypaudio.pa b/polyp/polypaudio.pa
index 0989a78d..71513565 100755
--- a/polyp/polypaudio.pa
+++ b/polyp/polypaudio.pa
@@ -18,33 +18,41 @@
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-# Load audio drivers
+# Load audio drivers statically
+
#load module-alsa-sink
#load module-alsa-source device=plughw:1,0
-#load module-oss device="/dev/dsp"
+#load module-oss device="/dev/dsp" sink_name=output source_name=input
#load module-oss-mmap device="/dev/dsp"
+# Load audio drivers automatically on access
+
+#autoload_sink_add output module-oss device="/dev/dsp" sink_name=output source_name=input
+#autoload_source_add input module-oss device="/dev/dsp" sink_name=output source_name=input
+autoload_sink_add output module-oss-mmap device="/dev/dsp" sink_name=output source_name=input
+autoload_source_add input module-oss-mmap device="/dev/dsp" sink_name=output source_name=input
+#autoload_sink_add output module-alsa-sink sink_name=output
+#autoload_source_add input module-alsa-source source_name=input
+
# Load several protocols
load module-esound-protocol-tcp
load module-simple-protocol-tcp
load module-native-protocol-unix
load module-cli-protocol-unix
-# Load X11 bell module
-load module-x11-bell
-
# Load the CLI module
load module-cli
-autoload_sink_add oss_output module-oss device="/dev/dsp" sink_name=oss_output source_name=oss_input
-autoload_source_add oss_input module-oss device="/dev/dsp" sink_name=oss_output source_name=oss_input
-
# Make some devices default
-sink_default oss_output
-source_default oss_input
+sink_default output
+source_default input
.nofail
# Load something to the sample cache
scache_load /usr/share/sounds/KDE_Notify.wav x11-bell
-scache_play x11-bell oss_output
+scache_play x11-bell output
+
+# Load X11 bell module
+load module-x11-bell sample=x11-bell sink=output
+
diff --git a/polyp/polyplib.h b/polyp/polyplib.h
index 391cb0c8..08e6a5a5 100644
--- a/polyp/polyplib.h
+++ b/polyp/polyplib.h
@@ -97,4 +97,34 @@ void pa_stream_finish_sample(struct pa_stream *p, void (*cb)(struct pa_stream*s,
void pa_context_play_sample(struct pa_context *c, const char *name, const char *dev, uint32_t volume, void (*cb)(struct pa_context *c, int success, void *userdata), void *userdata);
void pa_context_remove_sample(struct pa_context *c, const char *name, void (*cb)(struct pa_context *c, int success, void *userdata), void *userdata);
+struct pa_sink_info {
+ const char *name;
+ uint32_t index;
+ const char *description;
+ struct pa_sample_spec *sample_spec;
+ uint32_t owner_module;
+ uint32_t volume;
+ uint32_t monitor_source;
+ const char *monitor_source_name;
+ uint32_t latency;
+};
+
+void pa_context_get_sink_info_by_name(struct pa_context *c, const char *name, void (*cb)(struct pa_context *c, const struct pa_sink_info *i, void *userdata), void *userdata);
+void pa_context_get_sink_info_by_id(struct pa_context *c, uint32_t id, void (*cb)(struct pa_context *c, const struct pa_sink_info *i, void *userdata), void *userdata);
+void pa_context_get_sink_info_list(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_sink_info *i, void *userdata), void *userdata);
+
+struct pa_source_info {
+ const char *name;
+ uint32_t index;
+ const char *description;
+ struct pa_sample_spec *sample_spec;
+ uint32_t owner_module;
+ uint32_t monitor_of_sink;
+ const char *monitor_of_sink_name;
+};
+
+void pa_context_get_source_info_by_name(struct pa_context *c, const char *name, void (*cb)(struct pa_context *c, const struct pa_source_info *i, void *userdata), void *userdata);
+void pa_context_get_source_info_by_id(struct pa_context *c, uint32_t id, void (*cb)(struct pa_context *c, const struct pa_source_info *i, void *userdata), void *userdata);
+void pa_context_get_source_info_list(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_source_info *i, void *userdata), void *userdata);
+
#endif
diff --git a/polyp/protocol-esound.c b/polyp/protocol-esound.c
index 5f6f02fa..b11e1992 100644
--- a/polyp/protocol-esound.c
+++ b/polyp/protocol-esound.c
@@ -74,7 +74,7 @@ struct connection {
struct pa_sink_input *sink_input;
struct pa_source_output *source_output;
struct pa_memblockq *input_memblockq, *output_memblockq;
- void *fixed_source;
+ struct pa_defer_event *defer_event;
struct {
struct pa_memblock *current_memblock;
size_t memblock_index, fragment_size;
@@ -183,8 +183,8 @@ static void connection_free(struct connection *c) {
pa_iochannel_free(c->io);
- if (c->fixed_source)
- c->protocol->core->mainloop->cancel_fixed(c->protocol->core->mainloop, c->fixed_source);
+ if (c->defer_event)
+ c->protocol->core->mainloop->defer_free(c->defer_event);
if (c->scache_memchunk.memblock)
pa_memblock_unref(c->scache_memchunk.memblock);
@@ -197,8 +197,8 @@ static void* connection_write(struct connection *c, size_t length) {
size_t t, i;
assert(c);
- assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->enable_fixed);
- c->protocol->core->mainloop->enable_fixed(c->protocol->core->mainloop, c->fixed_source, 1);
+ assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->defer_enable);
+ c->protocol->core->mainloop->defer_enable(c->defer_event, 1);
t = c->write_data_length+length;
@@ -381,7 +381,7 @@ static int esd_proto_get_latency(struct connection *c, esd_proto_t request, cons
int latency, *lag;
assert(c && !data && length == 0);
- if (!(sink = pa_namereg(c->protocol->core, c->protocol->sink_name, PA_NAMEREG_SINK, 1)))
+ if (!(sink = pa_namereg_get(c->protocol->core, c->protocol->sink_name, PA_NAMEREG_SINK, 1)))
latency = 0;
else {
float usec = pa_sink_get_latency(sink);
@@ -845,8 +845,8 @@ static int do_write(struct connection *c) {
static void do_work(struct connection *c) {
assert(c);
- assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->enable_fixed);
- c->protocol->core->mainloop->enable_fixed(c->protocol->core->mainloop, c->fixed_source, 0);
+ assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->defer_enable);
+ c->protocol->core->mainloop->defer_enable(c->defer_event, 0);
if (pa_iochannel_is_hungup(c->io))
goto fail;
@@ -872,11 +872,11 @@ static void io_callback(struct pa_iochannel*io, void *userdata) {
do_work(c);
}
-/*** fixed callback ***/
+/*** defer callback ***/
-static void fixed_callback(struct pa_mainloop_api*a, void *id, void *userdata) {
+static void defer_callback(struct pa_mainloop_api*a, struct pa_defer_event *e, void *userdata) {
struct connection *c = userdata;
- assert(a && c && c->fixed_source == id);
+ assert(a && c && c->defer_event == e);
do_work(c);
}
@@ -901,8 +901,8 @@ static void sink_input_drop_cb(struct pa_sink_input *i, size_t length) {
pa_memblockq_drop(c->input_memblockq, length);
/* do something */
- assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->enable_fixed);
- c->protocol->core->mainloop->enable_fixed(c->protocol->core->mainloop, c->fixed_source, 1);
+ assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->defer_enable);
+ c->protocol->core->mainloop->defer_enable(c->defer_event, 1);
}
static void sink_input_kill_cb(struct pa_sink_input *i) {
@@ -926,8 +926,8 @@ static void source_output_push_cb(struct pa_source_output *o, const struct pa_me
pa_memblockq_push(c->output_memblockq, chunk, 0);
/* do something */
- assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->enable_fixed);
- c->protocol->core->mainloop->enable_fixed(c->protocol->core->mainloop, c->fixed_source, 1);
+ assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->defer_enable);
+ c->protocol->core->mainloop->defer_enable(c->defer_event, 1);
}
static void source_output_kill_cb(struct pa_source_output *o) {
@@ -981,8 +981,9 @@ static void on_connection(struct pa_socket_server*s, struct pa_iochannel *io, vo
c->scache_memchunk.memblock = NULL;
c->scache_name = NULL;
- c->fixed_source = c->protocol->core->mainloop->source_fixed(c->protocol->core->mainloop, fixed_callback, c);
- c->protocol->core->mainloop->enable_fixed(c->protocol->core->mainloop, c->fixed_source, 0);
+ c->defer_event = c->protocol->core->mainloop->defer_new(c->protocol->core->mainloop, defer_callback, c);
+ assert(c->defer_event);
+ c->protocol->core->mainloop->defer_enable(c->defer_event, 0);
pa_idxset_put(c->protocol->connections, c, &c->index);
}
diff --git a/polyp/protocol-native.c b/polyp/protocol-native.c
index c0aef180..778677b3 100644
--- a/polyp/protocol-native.c
+++ b/polyp/protocol-native.c
@@ -127,6 +127,8 @@ static void command_create_upload_stream(struct pa_pdispatch *pd, uint32_t comma
static void command_finish_upload_stream(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata);
static void command_play_sample(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata);
static void command_remove_sample(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata);
+static void command_get_info(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata);
+static void command_get_info_list(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata);
static const struct pa_pdispatch_command command_table[PA_COMMAND_MAX] = {
[PA_COMMAND_ERROR] = { NULL },
@@ -150,6 +152,10 @@ static const struct pa_pdispatch_command command_table[PA_COMMAND_MAX] = {
[PA_COMMAND_FINISH_UPLOAD_STREAM] = { command_finish_upload_stream },
[PA_COMMAND_PLAY_SAMPLE] = { command_play_sample },
[PA_COMMAND_REMOVE_SAMPLE] = { command_remove_sample },
+ [PA_COMMAND_GET_SINK_INFO] = { command_get_info },
+ [PA_COMMAND_GET_SOURCE_INFO] = { command_get_info },
+ [PA_COMMAND_GET_SINK_INFO_LIST] = { command_get_info_list },
+ [PA_COMMAND_GET_SOURCE_INFO_LIST] = { command_get_info_list },
};
/* structure management */
@@ -923,6 +929,122 @@ static void command_remove_sample(struct pa_pdispatch *pd, uint32_t command, uin
pa_pstream_send_simple_ack(c->pstream, tag);
}
+static void sink_fill_tagstruct(struct pa_tagstruct *t, struct pa_sink *sink) {
+ assert(t && sink);
+ pa_tagstruct_putu32(t, sink->index);
+ pa_tagstruct_puts(t, sink->name);
+ pa_tagstruct_puts(t, sink->description);
+ pa_tagstruct_put_sample_spec(t, &sink->sample_spec);
+ pa_tagstruct_putu32(t, sink->owner ? sink->owner->index : (uint32_t) -1);
+ pa_tagstruct_putu32(t, sink->volume);
+ pa_tagstruct_putu32(t, sink->monitor_source->index);
+ pa_tagstruct_puts(t, sink->monitor_source->name);
+ pa_tagstruct_putu32(t, pa_sink_get_latency(sink));
+}
+
+static void source_fill_tagstruct(struct pa_tagstruct *t, struct pa_source *source) {
+ assert(t && source);
+ pa_tagstruct_putu32(t, source->index);
+ pa_tagstruct_puts(t, source->name);
+ pa_tagstruct_puts(t, source->description);
+ pa_tagstruct_put_sample_spec(t, &source->sample_spec);
+ pa_tagstruct_putu32(t, source->owner ? source->owner->index : (uint32_t) -1);
+ pa_tagstruct_putu32(t, source->monitor_of ? source->monitor_of->index : (uint32_t) -1);
+ pa_tagstruct_puts(t, source->monitor_of ? source->monitor_of->name : "");
+}
+
+static void command_get_info(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) {
+ struct connection *c = userdata;
+ uint32_t index;
+ struct pa_sink *sink = NULL;
+ struct pa_source *source = NULL;
+ const char *name;
+ struct pa_tagstruct *reply;
+ assert(c && t);
+
+ if (pa_tagstruct_getu32(t, &index) < 0 ||
+ pa_tagstruct_gets(t, &name) < 0 ||
+ !pa_tagstruct_eof(t)) {
+ protocol_error(c);
+ return;
+ }
+
+ if (!c->authorized) {
+ pa_pstream_send_error(c->pstream, tag, PA_ERROR_ACCESS);
+ return;
+ }
+
+ if (command == PA_COMMAND_GET_SINK_INFO) {
+ if (index != (uint32_t) -1)
+ sink = pa_idxset_get_by_index(c->protocol->core->sinks, index);
+ else
+ sink = pa_namereg_get(c->protocol->core, *name ? name : NULL, PA_NAMEREG_SINK, 1);
+ } else {
+ assert(command == PA_COMMAND_GET_SOURCE_INFO);
+ if (index != (uint32_t) -1)
+ source = pa_idxset_get_by_index(c->protocol->core->sources, index);
+ else
+ source = pa_namereg_get(c->protocol->core, *name ? name : NULL, PA_NAMEREG_SOURCE, 1);
+ }
+
+ if (!sink && !source) {
+ pa_pstream_send_error(c->pstream, tag, PA_ERROR_NOENTITY);
+ return;
+ }
+
+ reply = pa_tagstruct_new(NULL, 0);
+ assert(reply);
+ pa_tagstruct_putu32(reply, PA_COMMAND_REPLY);
+ pa_tagstruct_putu32(reply, tag);
+ if (sink)
+ sink_fill_tagstruct(reply, sink);
+ else
+ source_fill_tagstruct(reply, source);
+ pa_pstream_send_tagstruct(c->pstream, reply);
+}
+
+static void command_get_info_list(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) {
+ struct connection *c = userdata;
+ struct pa_idxset *i;
+ uint32_t index;
+ void *p;
+ struct pa_tagstruct *reply;
+ assert(c && t);
+
+ if (!pa_tagstruct_eof(t)) {
+ protocol_error(c);
+ return;
+ }
+
+ if (!c->authorized) {
+ pa_pstream_send_error(c->pstream, tag, PA_ERROR_ACCESS);
+ return;
+ }
+
+ reply = pa_tagstruct_new(NULL, 0);
+ assert(reply);
+ pa_tagstruct_putu32(reply, PA_COMMAND_REPLY);
+ pa_tagstruct_putu32(reply, tag);
+
+ if (command == PA_COMMAND_GET_SINK_INFO_LIST)
+ i = c->protocol->core->sinks;
+ else {
+ assert(command == PA_COMMAND_GET_SOURCE_INFO_LIST);
+ i = c->protocol->core->sources;
+ }
+
+ for (p = pa_idxset_first(i, &index); p; p = pa_idxset_next(i, &index)) {
+ if (command == PA_COMMAND_GET_SINK_INFO_LIST)
+ sink_fill_tagstruct(reply, p);
+ else {
+ assert(command == PA_COMMAND_GET_SOURCE_INFO_LIST);
+ source_fill_tagstruct(reply, p);
+ }
+ }
+
+ pa_pstream_send_tagstruct(c->pstream, reply);
+}
+
/*** pstream callbacks ***/
static void pstream_packet_callback(struct pa_pstream *p, struct pa_packet *packet, void *userdata) {
diff --git a/polyp/protocol-simple.c b/polyp/protocol-simple.c
index 4b3b1513..a95b356c 100644
--- a/polyp/protocol-simple.c
+++ b/polyp/protocol-simple.c
@@ -45,7 +45,7 @@ struct connection {
struct pa_source_output *source_output;
struct pa_client *client;
struct pa_memblockq *input_memblockq, *output_memblockq;
- void *fixed_source;
+ struct pa_defer_event *defer_event;
struct {
struct pa_memblock *current_memblock;
@@ -91,8 +91,8 @@ static void connection_free(struct connection *c) {
pa_memblockq_free(c->input_memblockq);
if (c->output_memblockq)
pa_memblockq_free(c->output_memblockq);
- if (c->fixed_source)
- c->protocol->core->mainloop->cancel_fixed(c->protocol->core->mainloop, c->fixed_source);
+ if (c->defer_event)
+ c->protocol->core->mainloop->defer_free(c->defer_event);
pa_xfree(c);
}
@@ -169,8 +169,8 @@ static int do_write(struct connection *c) {
static void do_work(struct connection *c) {
assert(c);
- assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->enable_fixed);
- c->protocol->core->mainloop->enable_fixed(c->protocol->core->mainloop, c->fixed_source, 0);
+ assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->defer_enable);
+ c->protocol->core->mainloop->defer_enable(c->defer_event, 0);
if (pa_iochannel_is_hungup(c->io))
goto fail;
@@ -209,8 +209,8 @@ static void sink_input_drop_cb(struct pa_sink_input *i, size_t length) {
pa_memblockq_drop(c->input_memblockq, length);
/* do something */
- assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->enable_fixed);
- c->protocol->core->mainloop->enable_fixed(c->protocol->core->mainloop, c->fixed_source, 1);
+ assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->defer_enable);
+ c->protocol->core->mainloop->defer_enable(c->defer_event, 1);
}
static void sink_input_kill_cb(struct pa_sink_input *i) {
@@ -234,8 +234,8 @@ static void source_output_push_cb(struct pa_source_output *o, const struct pa_me
pa_memblockq_push(c->output_memblockq, chunk, 0);
/* do something */
- assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->enable_fixed);
- c->protocol->core->mainloop->enable_fixed(c->protocol->core->mainloop, c->fixed_source, 1);
+ assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->defer_enable);
+ c->protocol->core->mainloop->defer_enable(c->defer_event, 1);
}
static void source_output_kill_cb(struct pa_source_output *o) {
@@ -261,9 +261,9 @@ static void io_callback(struct pa_iochannel*io, void *userdata) {
/*** fixed callback ***/
-static void fixed_callback(struct pa_mainloop_api*a, void *id, void *userdata) {
+static void defer_callback(struct pa_mainloop_api*a, struct pa_defer_event *e, void *userdata) {
struct connection *c = userdata;
- assert(a && c && c->fixed_source == id);
+ assert(a && c && c->defer_event == e);
do_work(c);
}
@@ -280,7 +280,7 @@ static void on_connection(struct pa_socket_server*s, struct pa_iochannel *io, vo
c->io = io;
c->sink_input = NULL;
c->source_output = NULL;
- c->fixed_source = NULL;
+ c->defer_event = NULL;
c->input_memblockq = c->output_memblockq = NULL;
c->protocol = p;
c->playback.current_memblock = NULL;
@@ -353,9 +353,9 @@ static void on_connection(struct pa_socket_server*s, struct pa_iochannel *io, vo
pa_iochannel_set_callback(c->io, io_callback, c);
pa_idxset_put(p->connections, c, NULL);
- c->fixed_source = p->core->mainloop->source_fixed(p->core->mainloop, fixed_callback, c);
- assert(c->fixed_source);
- p->core->mainloop->enable_fixed(p->core->mainloop, c->fixed_source, 0);
+ c->defer_event = p->core->mainloop->defer_new(p->core->mainloop, defer_callback, c);
+ assert(c->defer_event);
+ p->core->mainloop->defer_enable(c->defer_event, 0);
return;
diff --git a/polyp/pstream.c b/polyp/pstream.c
index e7441b24..4f071e4a 100644
--- a/polyp/pstream.c
+++ b/polyp/pstream.c
@@ -58,7 +58,7 @@ struct item_info {
struct pa_pstream {
struct pa_mainloop_api *mainloop;
- struct mainloop_source *mainloop_source;
+ struct pa_defer_event *defer_event;
struct pa_iochannel *io;
struct pa_queue *send_queue;
@@ -98,7 +98,7 @@ static void do_read(struct pa_pstream *p);
static void do_something(struct pa_pstream *p) {
assert(p && !p->shall_free);
- p->mainloop->enable_fixed(p->mainloop, p->mainloop_source, 0);
+ p->mainloop->defer_enable(p->defer_event, 0);
if (p->dead)
return;
@@ -139,9 +139,9 @@ static void io_callback(struct pa_iochannel*io, void *userdata) {
do_something(p);
}
-static void fixed_callback(struct pa_mainloop_api *m, void *id, void*userdata) {
+static void defer_callback(struct pa_mainloop_api *m, struct pa_defer_event *e, void*userdata) {
struct pa_pstream *p = userdata;
- assert(p && p->mainloop_source == id && p->mainloop == m);
+ assert(p && p->defer_event == e && p->mainloop == m);
do_something(p);
}
@@ -159,8 +159,8 @@ struct pa_pstream *pa_pstream_new(struct pa_mainloop_api *m, struct pa_iochannel
p->die_callback_userdata = NULL;
p->mainloop = m;
- p->mainloop_source = m->source_fixed(m, fixed_callback, p);
- m->enable_fixed(m, p->mainloop_source, 0);
+ p->defer_event = m->defer_new(m, defer_callback, p);
+ m->defer_enable(p->defer_event, 0);
p->send_queue = pa_queue_new();
assert(p->send_queue);
@@ -223,7 +223,7 @@ void pa_pstream_free(struct pa_pstream *p) {
if (p->read.packet)
pa_packet_unref(p->read.packet);
- p->mainloop->cancel_fixed(p->mainloop, p->mainloop_source);
+ p->mainloop->defer_free(p->defer_event);
pa_xfree(p);
}
@@ -236,7 +236,7 @@ void pa_pstream_send_packet(struct pa_pstream*p, struct pa_packet *packet) {
i->packet = pa_packet_ref(packet);
pa_queue_push(p->send_queue, i);
- p->mainloop->enable_fixed(p->mainloop, p->mainloop_source, 1);
+ p->mainloop->defer_enable(p->defer_event, 1);
}
void pa_pstream_send_memblock(struct pa_pstream*p, uint32_t channel, int32_t delta, const struct pa_memchunk *chunk) {
@@ -252,7 +252,7 @@ void pa_pstream_send_memblock(struct pa_pstream*p, uint32_t channel, int32_t del
pa_memblock_ref(i->chunk.memblock);
pa_queue_push(p->send_queue, i);
- p->mainloop->enable_fixed(p->mainloop, p->mainloop_source, 1);
+ p->mainloop->defer_enable(p->defer_event, 1);
}
void pa_pstream_set_recieve_packet_callback(struct pa_pstream *p, void (*callback) (struct pa_pstream *p, struct pa_packet *packet, void *userdata), void *userdata) {
diff --git a/polyp/socket-client.c b/polyp/socket-client.c
index c0c355de..e8cb2f92 100644
--- a/polyp/socket-client.c
+++ b/polyp/socket-client.c
@@ -41,8 +41,8 @@
struct pa_socket_client {
struct pa_mainloop_api *mainloop;
int fd;
-
- void *io_source, *fixed_source;
+ struct pa_io_event *io_event;
+ struct pa_defer_event *defer_event;
void (*callback)(struct pa_socket_client*c, struct pa_iochannel *io, void *userdata);
void *userdata;
};
@@ -54,7 +54,8 @@ static struct pa_socket_client*pa_socket_client_new(struct pa_mainloop_api *m) {
c = pa_xmalloc(sizeof(struct pa_socket_client));
c->mainloop = m;
c->fd = -1;
- c->io_source = c->fixed_source = NULL;
+ c->io_event = NULL;
+ c->defer_event = NULL;
c->callback = NULL;
c->userdata = NULL;
return c;
@@ -95,19 +96,19 @@ failed:
return;
}
-static void connect_fixed_cb(struct pa_mainloop_api *m, void *id, void *userdata) {
+static void connect_fixed_cb(struct pa_mainloop_api *m, struct pa_defer_event *e, void *userdata) {
struct pa_socket_client *c = userdata;
- assert(m && c && c->fixed_source == id);
- m->cancel_fixed(m, c->fixed_source);
- c->fixed_source = NULL;
+ assert(m && c && c->defer_event == e);
+ m->defer_free(c->defer_event);
+ c->defer_event = NULL;
do_call(c);
}
-static void connect_io_cb(struct pa_mainloop_api*m, void *id, int fd, enum pa_mainloop_api_io_events events, void *userdata) {
+static void connect_io_cb(struct pa_mainloop_api*m, struct pa_io_event *e, int fd, enum pa_io_event_flags f, void *userdata) {
struct pa_socket_client *c = userdata;
- assert(m && c && c->io_source == id && fd >= 0);
- m->cancel_io(m, c->io_source);
- c->io_source = NULL;
+ assert(m && c && c->io_event == e && fd >= 0);
+ m->io_free(c->io_event);
+ c->io_event = NULL;
do_call(c);
}
@@ -123,11 +124,11 @@ static int do_connect(struct pa_socket_client *c, const struct sockaddr *sa, soc
return -1;
}
- c->io_source = c->mainloop->source_io(c->mainloop, c->fd, PA_MAINLOOP_API_IO_EVENT_OUTPUT, connect_io_cb, c);
- assert(c->io_source);
+ c->io_event = c->mainloop->io_new(c->mainloop, c->fd, PA_IO_EVENT_OUTPUT, connect_io_cb, c);
+ assert(c->io_event);
} else {
- c->fixed_source = c->mainloop->source_fixed(c->mainloop, connect_fixed_cb, c);
- assert(c->fixed_source);
+ c->defer_event = c->mainloop->defer_new(c->mainloop, connect_fixed_cb, c);
+ assert(c->defer_event);
}
return 0;
@@ -220,10 +221,10 @@ fail:
void pa_socket_client_free(struct pa_socket_client *c) {
assert(c && c->mainloop);
- if (c->io_source)
- c->mainloop->cancel_io(c->mainloop, c->io_source);
- if (c->fixed_source)
- c->mainloop->cancel_fixed(c->mainloop, c->fixed_source);
+ if (c->io_event)
+ c->mainloop->io_free(c->io_event);
+ if (c->defer_event)
+ c->mainloop->defer_free(c->defer_event);
if (c->fd >= 0)
close(c->fd);
pa_xfree(c);
diff --git a/polyp/socket-server.c b/polyp/socket-server.c
index 5f332f0c..6af2c286 100644
--- a/polyp/socket-server.c
+++ b/polyp/socket-server.c
@@ -46,16 +46,16 @@ struct pa_socket_server {
void (*on_connection)(struct pa_socket_server*s, struct pa_iochannel *io, void *userdata);
void *userdata;
- void *mainloop_source;
+ struct pa_io_event *io_event;
struct pa_mainloop_api *mainloop;
enum { SOCKET_SERVER_GENERIC, SOCKET_SERVER_IPV4, SOCKET_SERVER_UNIX } type;
};
-static void callback(struct pa_mainloop_api *mainloop, void *id, int fd, enum pa_mainloop_api_io_events events, void *userdata) {
+static void callback(struct pa_mainloop_api *mainloop, struct pa_io_event *e, int fd, enum pa_io_event_flags f, void *userdata) {
struct pa_socket_server *s = userdata;
struct pa_iochannel *io;
int nfd;
- assert(s && s->mainloop == mainloop && s->mainloop_source == id && id && fd >= 0 && fd == s->fd && events == PA_MAINLOOP_API_IO_EVENT_INPUT);
+ assert(s && s->mainloop == mainloop && s->io_event == e && e && fd >= 0 && fd == s->fd);
if ((nfd = accept(fd, NULL, NULL)) < 0) {
fprintf(stderr, "accept(): %s\n", strerror(errno));
@@ -89,8 +89,8 @@ struct pa_socket_server* pa_socket_server_new(struct pa_mainloop_api *m, int fd)
s->userdata = NULL;
s->mainloop = m;
- s->mainloop_source = m->source_io(m, fd, PA_MAINLOOP_API_IO_EVENT_INPUT, callback, s);
- assert(s->mainloop_source);
+ s->io_event = m->io_new(m, fd, PA_IO_EVENT_INPUT, callback, s);
+ assert(s->io_event);
s->type = SOCKET_SERVER_GENERIC;
@@ -193,7 +193,7 @@ void pa_socket_server_free(struct pa_socket_server*s) {
pa_xfree(s->filename);
}
- s->mainloop->cancel_io(s->mainloop, s->mainloop_source);
+ s->mainloop->io_free(s->io_event);
pa_xfree(s);
}
diff --git a/polyp/xmalloc.h b/polyp/xmalloc.h
index 5f58a8ad..45209b05 100644
--- a/polyp/xmalloc.h
+++ b/polyp/xmalloc.h
@@ -2,6 +2,7 @@
#define foomemoryhfoo
#include <sys/types.h>
+#include <stdlib.h>
void* pa_xmalloc(size_t l);
void *pa_xmalloc0(size_t l);