summaryrefslogtreecommitdiffstats
path: root/avahi-common/simple-watch.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2005-08-13 21:25:09 +0000
committerLennart Poettering <lennart@poettering.net>2005-08-13 21:25:09 +0000
commit4f0a5e7572a4257894b4bfede42c26d65152609e (patch)
tree21e3d5ee20716739590e5931859a4c2052161395 /avahi-common/simple-watch.c
parentd6d7d3769441b73ffb5b7af34fef823b41e66312 (diff)
* strip glib from avahi-core
* implement glib memory allocator * add new documentation file MALLOC * initialize pseudo-RNG from /dev/urandom in avahi-daemon * remove some gcc 4.0 warnings * beef up watch system with real timeouts * move GCC __attribute__ macros into its own header avahi-common/gccmacro.h * make use of GCC's sentinel attribute where it make sense * add malloc() implementations that abort on OOM and enable them by default git-svn-id: file:///home/lennart/svn/public/avahi/trunk@308 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe
Diffstat (limited to 'avahi-common/simple-watch.c')
-rw-r--r--avahi-common/simple-watch.c120
1 files changed, 81 insertions, 39 deletions
diff --git a/avahi-common/simple-watch.c b/avahi-common/simple-watch.c
index acc0923..3caf371 100644
--- a/avahi-common/simple-watch.c
+++ b/avahi-common/simple-watch.c
@@ -51,7 +51,8 @@ struct AvahiSimplePoll {
int n_pollfds, max_pollfds, rebuild_pollfds;
struct timeval wakeup;
- int use_wakeup;
+ AvahiWakeupCallback wakeup_callback;
+ void *wakeup_userdata;
int req_cleanup;
@@ -141,17 +142,24 @@ static void watch_free(AvahiWatch *w) {
w->simple_poll->req_cleanup = 1;
}
-static void set_wakeup_time(AvahiPoll *api, const struct timeval *tv) {
+static void set_wakeup(AvahiPoll *api, const struct timeval *tv, AvahiWakeupCallback callback, void *userdata) {
AvahiSimplePoll *s;
assert(api);
s = api->userdata;
- if (tv) {
- s->wakeup = *tv;
- s->use_wakeup = 1;
+ if (callback) {
+ if (tv)
+ s->wakeup = *tv;
+ else {
+ s->wakeup.tv_sec = 0;
+ s->wakeup.tv_usec = 0;
+ }
+
+ s->wakeup_callback = callback;
+ s->wakeup_userdata = userdata;
} else
- s->use_wakeup = 0;
+ s->wakeup_callback = NULL;
}
static void destroy_watch(AvahiWatch *w) {
@@ -190,10 +198,10 @@ AvahiSimplePoll *avahi_simple_poll_new(void) {
s->api.watch_new = watch_new;
s->api.watch_free = watch_free;
s->api.watch_update = watch_update;
- s->api.set_wakeup_time = set_wakeup_time;
+ s->api.set_wakeup = set_wakeup;
s->pollfds = NULL;
s->max_pollfds = s->n_pollfds = 0;
- s->use_wakeup = 0;
+ s->wakeup_callback = NULL;
s->rebuild_pollfds = 0;
s->quit = 0;
s->n_watches = 0;
@@ -248,41 +256,84 @@ static int rebuild(AvahiSimplePoll *s) {
return 0;
}
-int avahi_simple_poll_iterate(AvahiSimplePoll *s, int block) {
- int timeout, r, ret = 0;
+static int start_wakeup_callback(AvahiSimplePoll *s) {
+ AvahiWakeupCallback callback;
+ void *userdata;
+
assert(s);
- if (s->quit)
- return 1;
+ /* Reset the wakeup functions, but allow changing of the two
+ values from the callback function */
+
+ callback = s->wakeup_callback;
+ userdata = s->wakeup_userdata;
+ s->wakeup_callback = NULL;
+ s->wakeup_userdata = NULL;
+
+ assert(callback);
+
+ callback(&s->api, userdata);
+ return 0;
+}
+
+int avahi_simple_poll_iterate(AvahiSimplePoll *s, int timeout) {
+ int r;
+ assert(s);
+ /* Cleanup things first */
if (s->req_cleanup)
cleanup(s, 0);
-
+
+ /* Check whether a quit was requested */
+ if (s->quit)
+ return 1;
+
+ /* Do we need to rebuild our array of pollfds? */
if (s->rebuild_pollfds)
if (rebuild(s) < 0)
return -1;
- if (block) {
- if (s->use_wakeup) {
- struct timeval now;
- AvahiUsec usec;
+ /* Calculate the wakeup time */
+ if (s->wakeup_callback) {
+ struct timeval now;
+ int t;
+ AvahiUsec usec;
- gettimeofday(&now, NULL);
+ gettimeofday(&now, NULL);
+ usec = avahi_timeval_diff(&s->wakeup, &now);
- usec = avahi_timeval_diff(&s->wakeup, &now);
-
- timeout = usec <= 0 ? 0 : (int) (usec / 1000);
- } else
- timeout = -1;
- } else
- timeout = 0;
+ if (usec <= 0)
+ /* Timeout elapsed */
+
+ return start_wakeup_callback(s);
+
+ /* Calculate sleep time. We add 1ms because otherwise we'd
+ * wake up too early most of the time */
+ t = (int) (usec / 1000) + 1;
+
+ if (timeout < 0 || timeout > t)
+ timeout = t;
+ }
if ((r = poll(s->pollfds, s->n_pollfds, timeout)) < 0)
return -1;
- else if (r > 0) {
+ /* Check whether the wakeup time has been reached now */
+ if (s->wakeup_callback) {
+ struct timeval now;
+
+ gettimeofday(&now, NULL);
+
+ if (avahi_timeval_compare(&s->wakeup, &now) <= 0)
+ /* Time elapsed */
+ return start_wakeup_callback(s);
+ }
+
+ if (r > 0) {
AvahiWatch *w;
+ /* Look for some kind of I/O event */
+
for (w = s->watches; w; w = w->watches_next) {
if (w->dead)
@@ -291,24 +342,15 @@ int avahi_simple_poll_iterate(AvahiSimplePoll *s, int block) {
assert(w->idx >= 0);
assert(w->idx < s->n_pollfds);
- if (s->pollfds[w->idx].revents > 0)
+ if (s->pollfds[w->idx].revents > 0) {
+ /* We execute only on callback in every iteration */
w->callback(w, w->pollfd.fd, s->pollfds[w->idx].revents, w->userdata);
-
- if (s->quit) {
- ret = 1;
- goto finish;
+ return 0;
}
}
}
- ret = 0;
-
-finish:
-
- if (s->req_cleanup)
- cleanup(s, 0);
-
- return ret;
+ return 0;
}
void avahi_simple_poll_quit(AvahiSimplePoll *w) {