#include "../polypcore/winsock.h"
-#include <polypcore/util.h>
+#ifndef HAVE_PIPE
+#include "../polypcore/pipe.h"
+#endif
+
+#include <polypcore/core-error.h>
+#include <polyp/timeval.h>
+#include <polyp/xmalloc.h>
+
+#include <polypcore/core-util.h>
#include <polypcore/idxset.h>
-#include <polypcore/xmalloc.h>
#include <polypcore/log.h>
#include "mainloop.h"
STATE_POLLED,
STATE_QUIT
} state;
+
+ pa_poll_func poll_func;
+ void *poll_func_userdata;
};
/* IO events */
m = a->userdata;
assert(a == &m->api);
- pa_mainloop_wakeup(m);
-
e = pa_xmalloc(sizeof(pa_io_event));
e->mainloop = m;
e->dead = 0;
pa_idxset_put(m->io_events, e, NULL);
m->rebuild_pollfds = 1;
+
+ pa_mainloop_wakeup(m);
+
return e;
}
static void mainloop_io_enable(pa_io_event *e, pa_io_event_flags_t events) {
assert(e && e->mainloop);
- pa_mainloop_wakeup(e->mainloop);
-
e->events = events;
e->mainloop->rebuild_pollfds = 1;
+
+ pa_mainloop_wakeup(e->mainloop);
}
static void mainloop_io_free(pa_io_event *e) {
assert(e && e->mainloop);
- pa_mainloop_wakeup(e->mainloop);
-
e->dead = e->mainloop->io_events_scan_dead = e->mainloop->rebuild_pollfds = 1;
+
+ pa_mainloop_wakeup(e->mainloop);
}
static void mainloop_io_set_destroy(pa_io_event *e, void (*callback)(pa_mainloop_api*a, pa_io_event *e, void *userdata)) {
pa_idxset_put(m->defer_events, e, NULL);
m->deferred_pending++;
+
+ pa_mainloop_wakeup(e->mainloop);
+
return e;
}
if (e->enabled && !b) {
assert(e->mainloop->deferred_pending > 0);
e->mainloop->deferred_pending--;
- } else if (!e->enabled && b)
+ } else if (!e->enabled && b) {
e->mainloop->deferred_pending++;
+ pa_mainloop_wakeup(e->mainloop);
+ }
e->enabled = b;
}
m = a->userdata;
assert(a == &m->api);
- pa_mainloop_wakeup(m);
-
e = pa_xmalloc(sizeof(pa_time_event));
e->mainloop = m;
e->dead = 0;
e->destroy_callback = NULL;
pa_idxset_put(m->time_events, e, NULL);
+
+ if (e->enabled)
+ pa_mainloop_wakeup(m);
return e;
}
static void mainloop_time_restart(pa_time_event *e, const struct timeval *tv) {
assert(e);
- pa_mainloop_wakeup(e->mainloop);
-
if (tv) {
e->enabled = 1;
e->timeval = *tv;
+
+ pa_mainloop_wakeup(e->mainloop);
} else
e->enabled = 0;
}
static void mainloop_time_free(pa_time_event *e) {
assert(e);
- pa_mainloop_wakeup(e->mainloop);
-
e->dead = e->mainloop->time_events_scan_dead = 1;
+
+ /* no wakeup needed here. Think about it! */
}
static void mainloop_time_set_destroy(pa_time_event *e, void (*callback)(pa_mainloop_api*a, pa_time_event *e, void *userdata)) {
m = a->userdata;
assert(a == &m->api);
- pa_mainloop_wakeup(m);
-
- m->quit = 1;
- m->retval = retval;
+ pa_mainloop_quit(m, retval);
}
static const pa_mainloop_api vtable = {
m = pa_xmalloc(sizeof(pa_mainloop));
-#ifndef OS_IS_WIN32
if (pipe(m->wakeup_pipe) < 0) {
+ pa_log_error(__FILE__": ERROR: cannot create wakeup pipe");
pa_xfree(m);
return NULL;
}
pa_make_nonblock_fd(m->wakeup_pipe[0]);
pa_make_nonblock_fd(m->wakeup_pipe[1]);
-#else
- m->wakeup_pipe[0] = -1;
- m->wakeup_pipe[1] = -1;
-#endif
m->io_events = pa_idxset_new(NULL, NULL);
m->defer_events = pa_idxset_new(NULL, NULL);
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->max_pollfds = m->n_pollfds = 0;
+ m->rebuild_pollfds = 1;
m->quit = m->retval = 0;
m->deferred_pending = 0;
m->state = STATE_PASSIVE;
+
+ m->poll_func = NULL;
+ m->poll_func_userdata = NULL;
+
+ m->retval = -1;
return m;
}
void pa_mainloop_free(pa_mainloop* m) {
int all = 1;
- assert(m && (m->state != STATE_POLLING));
+ assert(m);
pa_idxset_foreach(m->io_events, io_foreach, &all);
pa_idxset_foreach(m->time_events, time_foreach, &all);
assert(m);
if (m->wakeup_pipe[1] >= 0)
- write(m->wakeup_pipe[1], &c, sizeof(c));
+ pa_write(m->wakeup_pipe[1], &c, sizeof(c));
}
static void clear_wakeup(pa_mainloop *m) {
if (m->wakeup_pipe[0] < 0)
return;
- while (read(m->wakeup_pipe[0], &c, sizeof(c)) == sizeof(c));
+ while (pa_read(m->wakeup_pipe[0], &c, sizeof(c)) == sizeof(c));
}
int pa_mainloop_prepare(pa_mainloop *m, int timeout) {
if (m->deferred_pending)
r = 0;
else {
- r = poll(m->pollfds, m->n_pollfds, m->prepared_timeout);
+ if (m->poll_func)
+ r = m->poll_func(m->pollfds, m->n_pollfds, m->prepared_timeout, m->poll_func_userdata);
+ else
+ r = poll(m->pollfds, m->n_pollfds, m->prepared_timeout);
if (r < 0) {
if (errno == EINTR)
r = 0;
else
- pa_log(__FILE__": poll(): %s", strerror(errno));
+ pa_log(__FILE__": poll(): %s", pa_cstrerror(errno));
}
}
return 0;
}
-void pa_mainloop_quit(pa_mainloop *m, int r) {
+void pa_mainloop_quit(pa_mainloop *m, int retval) {
assert(m);
+
+ m->quit = 1;
+ m->retval = retval;
pa_mainloop_wakeup(m);
- m->quit = r;
}
pa_mainloop_api* pa_mainloop_get_api(pa_mainloop*m) {
return &m->api;
}
+void pa_mainloop_set_poll_func(pa_mainloop *m, pa_poll_func poll_func, void *userdata) {
+ assert(m);
+
+ m->poll_func = poll_func;
+ m->poll_func_userdata = userdata;
+}
+
+
#if 0
void pa_mainloop_dump(pa_mainloop *m) {
assert(m);