summaryrefslogtreecommitdiffstats
path: root/polyp
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2006-02-13 13:28:45 +0000
committerPierre Ossman <ossman@cendio.se>2006-02-13 13:28:45 +0000
commitbbaf1543bd77e5c428e5e4c7d40fde0a42bf3daf (patch)
tree265976ec19240e72faad21faea37b7207bd6e50c /polyp
parent4ab432a81952b5ef608775522d27ad9709b97307 (diff)
Split mainloop_iterate() into three, distinct parts. Allows for more flexible
use, like having the poll() run in a separate thread. git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@478 fefdeb5f-60dc-0310-8127-8f9354f1896f
Diffstat (limited to 'polyp')
-rw-r--r--polyp/mainloop.c157
-rw-r--r--polyp/mainloop.h25
2 files changed, 133 insertions, 49 deletions
diff --git a/polyp/mainloop.c b/polyp/mainloop.c
index 26ba2425..e131e1a1 100644
--- a/polyp/mainloop.c
+++ b/polyp/mainloop.c
@@ -84,10 +84,20 @@ struct pa_mainloop {
unsigned max_pollfds, n_pollfds;
int rebuild_pollfds;
- int quit, running, retval;
+ int prepared_timeout;
+
+ int quit, retval;
pa_mainloop_api api;
int deferred_pending;
+
+ enum {
+ STATE_PASSIVE,
+ STATE_PREPARED,
+ STATE_POLLING,
+ STATE_POLLED,
+ STATE_QUIT
+ } state;
};
/* IO events */
@@ -145,11 +155,7 @@ static void mainloop_io_enable(pa_io_event *e, pa_io_event_flags_t 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) |
- POLLERR | POLLHUP;
+ e->mainloop->rebuild_pollfds = 1;
}
static void mainloop_io_free(pa_io_event *e) {
@@ -310,12 +316,14 @@ pa_mainloop *pa_mainloop_new(void) {
m->pollfds = NULL;
m->max_pollfds = m->n_pollfds = m->rebuild_pollfds = 0;
- m->quit = m->running = m->retval = 0;
+ m->quit = m->retval = 0;
m->api = vtable;
m->api.userdata = m;
m->deferred_pending = 0;
+
+ m->state = STATE_PASSIVE;
return m;
}
@@ -367,7 +375,7 @@ static int defer_foreach(void *p, PA_GCC_UNUSED uint32_t idx, int *del, void*use
void pa_mainloop_free(pa_mainloop* m) {
int all = 1;
- assert(m);
+ assert(m && (m->state != STATE_POLLING));
pa_idxset_foreach(m->io_events, io_foreach, &all);
pa_idxset_foreach(m->time_events, time_foreach, &all);
@@ -427,6 +435,8 @@ static void rebuild_pollfds(pa_mainloop *m) {
p++;
m->n_pollfds++;
}
+
+ m->rebuild_pollfds = 0;
}
static int dispatch_pollfds(pa_mainloop *m) {
@@ -548,65 +558,122 @@ static int dispatch_timeout(pa_mainloop *m) {
return r;
}
-int pa_mainloop_iterate(pa_mainloop *m, int block, int *retval) {
- int r, t, dispatched = 0;
- assert(m && !m->running);
+int pa_mainloop_prepare(pa_mainloop *m, int timeout) {
+ int dispatched = 0;
+
+ assert(m && (m->state == STATE_PASSIVE));
- m->running ++;
+ scan_dead(m);
if (m->quit)
goto quit;
- scan_dead(m);
dispatched += dispatch_defer(m);
- if(m->quit)
+ if (m->quit)
goto quit;
-
- if (m->rebuild_pollfds) {
+
+ if (m->rebuild_pollfds)
rebuild_pollfds(m);
- m->rebuild_pollfds = 0;
- }
- t = block ? calc_next_timeout(m) : 0;
+ m->prepared_timeout = calc_next_timeout(m);
+ if ((timeout >= 0) && (m->prepared_timeout > timeout))
+ m->prepared_timeout = timeout;
- r = poll(m->pollfds, m->n_pollfds, t);
+ m->state = STATE_PREPARED;
- if (r < 0) {
- if (errno == EINTR)
- r = 0;
- else
- pa_log(__FILE__": select(): %s\n", strerror(errno));
- } else {
- dispatched += dispatch_timeout(m);
+ return dispatched;
- if(m->quit)
- goto quit;
-
- if (r > 0) {
- dispatched += dispatch_pollfds(m);
+quit:
- if(m->quit)
- goto quit;
- }
- }
-
- m->running--;
+ m->state = STATE_QUIT;
-/* pa_log("dispatched: %i\n", dispatched); */
+ return -2;
+}
+
+int pa_mainloop_poll(pa_mainloop *m) {
+ int r;
+
+ assert(m && (m->state == STATE_PREPARED));
+
+ m->state = STATE_POLLING;
+
+ r = poll(m->pollfds, m->n_pollfds, m->prepared_timeout);
+
+ if ((r < 0) && (errno == EINTR))
+ r = 0;
+
+ if (r < 0)
+ m->state = STATE_PASSIVE;
+ else
+ m->state = STATE_POLLED;
+
+ return r;
+}
+
+int pa_mainloop_dispatch(pa_mainloop *m) {
+ int dispatched = 0;
+
+ assert(m && (m->state == STATE_POLLED));
+
+ dispatched += dispatch_timeout(m);
+
+ if (m->quit)
+ goto quit;
- return r < 0 ? -1 : dispatched;
+ dispatched += dispatch_pollfds(m);
+
+ if (m->quit)
+ goto quit;
+
+ m->state = STATE_PASSIVE;
+
+ return dispatched;
quit:
-
- m->running--;
-
- if (retval)
- *retval = m->retval;
+
+ m->state = STATE_QUIT;
return -2;
}
+int pa_mainloop_get_retval(pa_mainloop *m) {
+ assert(m);
+ return m->retval;
+}
+
+int pa_mainloop_iterate(pa_mainloop *m, int block, int *retval) {
+ int r, dispatched = 0;
+
+ assert(m);
+
+ r = pa_mainloop_prepare(m, block ? -1 : 0);
+ if (r < 0) {
+ if ((r == -2) && retval)
+ *retval = pa_mainloop_get_retval(m);
+ return r;
+ }
+
+ dispatched += r;
+
+ r = pa_mainloop_poll(m);
+ if (r < 0) {
+ pa_log(__FILE__": poll(): %s\n", strerror(errno));
+ return r;
+ }
+
+ r = pa_mainloop_dispatch(m);
+ if (r < 0) {
+ if ((r == -2) && retval)
+ *retval = pa_mainloop_get_retval(m);
+ return r;
+ }
+
+ dispatched += r;
+
+ return dispatched;
+}
+
int pa_mainloop_run(pa_mainloop *m, int *retval) {
int r;
while ((r = pa_mainloop_iterate(m, 1, retval)) >= 0);
diff --git a/polyp/mainloop.h b/polyp/mainloop.h
index 06764907..2be9e6ff 100644
--- a/polyp/mainloop.h
+++ b/polyp/mainloop.h
@@ -46,10 +46,27 @@ pa_mainloop *pa_mainloop_new(void);
/** Free a main loop object */
void pa_mainloop_free(pa_mainloop* m);
-/** Run a single iteration of the main loop. Returns a negative value
-on error or exit request. If block is nonzero, block for events if
-none are queued. Optionally return the return value as specified with
-the main loop's quit() routine in the integer variable retval points
+
+/** Prepare for a single iteration of the main loop. Returns a negative value
+on error or exit request. timeout specifies a maximum timeout for the subsequent
+poll, or -1 for blocking behaviour. Defer events are also dispatched when this
+function is called. On success returns the number of source dispatched in this
+iteration.*/
+int pa_mainloop_prepare(pa_mainloop *m, int timeout);
+/** Execute the previously prepared poll. Returns a negative value on error.*/
+int pa_mainloop_poll(pa_mainloop *m);
+/** Dispatch timeout and io events from the previously executed poll. Returns
+a negative value on error. On success returns the number of source dispatched. */
+int pa_mainloop_dispatch(pa_mainloop *m);
+
+/** Return the return value as specified with the main loop's quit() routine. */
+int pa_mainloop_get_retval(pa_mainloop *m);
+
+/** Run a single iteration of the main loop. This is a convenience function
+for pa_mainloop_prepare(), pa_mainloop_poll() and pa_mainloop_dispatch().
+Returns a negative value on error or exit request. If block is nonzero,
+block for events if none are queued. Optionally return the return value as
+specified with the main loop's quit() routine in the integer variable retval points
to. On success returns the number of source dispatched in this iteration. */
int pa_mainloop_iterate(pa_mainloop *m, int block, int *retval);