static gboolean prepare_func(GSource *source, gint *timeout) { AvahiGLibPoll *g = (AvahiGLibPoll*) source; AvahiTimeout *next_timeout; g_assert(g); g_assert(timeout); if (g->watch_req_cleanup) cleanup_watches(g, 0); if (g->timeout_req_cleanup) cleanup_timeouts(g, 0); if ((next_timeout = find_next_timeout(g))) { GTimeVal now; struct timeval tvnow; AvahiUsec usec; g_source_get_current_time(source, &now); tvnow.tv_sec = now.tv_sec; tvnow.tv_usec = now.tv_usec; usec = avahi_timeval_diff(&next_timeout->expiry, &tvnow); if (usec <= 0) { *timeout = 0; return TRUE; } *timeout = (gint) (usec / 1000); } else *timeout = -1; return FALSE; }
AvahiUsec avahi_age(const struct timeval *a) { struct timeval now; assert(a); gettimeofday(&now, NULL); return avahi_timeval_diff(&now, a); }
AvahiUsec avahi_timeval_diff(const struct timeval *a, const struct timeval *b) { assert(a); assert(b); if (avahi_timeval_compare(a, b) < 0) return - avahi_timeval_diff(b, a); return ((AvahiUsec) a->tv_sec - b->tv_sec)*1000000 + a->tv_usec - b->tv_usec; }
int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[]) { struct timeval a = { 5, 5 }, b; b = a; printf("%li.%li\n", a.tv_sec, a.tv_usec); avahi_timeval_add(&a, -50); printf("%li.%li\n", a.tv_sec, a.tv_usec); printf("%lli\n", (long long) avahi_timeval_diff(&a, &b)); return 0; }
int avahi_cache_entry_half_ttl(AvahiCache *c, AvahiCacheEntry *e) { struct timeval now; unsigned age; assert(c); assert(e); gettimeofday(&now, NULL); age = (unsigned) (avahi_timeval_diff(&now, &e->timestamp)/1000000); /* avahi_log_debug("age: %lli, ttl/2: %u", age, e->record->ttl); */ return age >= e->record->ttl/2; }
static void* start_poof_callback(AvahiCache *c, AvahiKey *pattern, AvahiCacheEntry *e, void *userdata) { AvahiAddress *a = userdata; struct timeval now; assert(c); assert(pattern); assert(e); assert(a); gettimeofday(&now, NULL); switch (e->state) { case AVAHI_CACHE_VALID: /* The entry was perfectly valid till, now, so let's enter * POOF mode */ e->state = AVAHI_CACHE_POOF; e->poof_address = *a; e->poof_timestamp = now; e->poof_num = 0; break; case AVAHI_CACHE_POOF: if (avahi_timeval_diff(&now, &e->poof_timestamp) < 1000000) break; e->poof_timestamp = now; e->poof_address = *a; e->poof_num ++; /* This is the 4th time we got no response, so let's * f*****g remove this entry. */ if (e->poof_num > 3) expire_in_one_second(c, e, AVAHI_CACHE_POOF_FINAL); break; default: ; } return NULL; }
int avahi_simple_poll_prepare(AvahiSimplePoll *s, int timeout) { AvahiTimeout *next_timeout; assert(s); assert(s->state == STATE_INIT || s->state == STATE_DISPATCHED || s->state == STATE_FAILURE); s->state = STATE_PREPARING; /* Clear pending wakeup requests */ clear_wakeup(s); /* Cleanup things first */ if (s->watch_req_cleanup) cleanup_watches(s, 0); if (s->timeout_req_cleanup) cleanup_timeouts(s, 0); /* Check whether a quit was requested */ if (s->quit) { s->state = STATE_QUIT; return 1; } /* Do we need to rebuild our array of pollfds? */ if (s->rebuild_pollfds) if (rebuild(s) < 0) { s->state = STATE_FAILURE; return -1; } /* Calculate the wakeup time */ if ((next_timeout = find_next_timeout(s))) { struct timeval now; int t; AvahiUsec usec; if (next_timeout->expiry.tv_sec == 0 && next_timeout->expiry.tv_usec == 0) { /* Just a shortcut so that we don't need to call gettimeofday() */ timeout = 0; goto finish; } gettimeofday(&now, NULL); usec = avahi_timeval_diff(&next_timeout->expiry, &now); if (usec <= 0) { /* Timeout elapsed */ timeout = 0; goto finish; } /* 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; } finish: s->prepared_timeout = timeout; s->state = STATE_PREPARED; return 0; }
void avahi_cache_update(AvahiCache *c, AvahiRecord *r, int cache_flush, const AvahiAddress *a) { /* char *txt; */ assert(c); assert(r && r->ref >= 1); /* txt = avahi_record_to_string(r); */ if (r->ttl == 0) { /* This is a goodbye request */ AvahiCacheEntry *e; if ((e = lookup_record(c, r))) expire_in_one_second(c, e, AVAHI_CACHE_GOODBYE_FINAL); } else { AvahiCacheEntry *e = NULL, *first; struct timeval now; gettimeofday(&now, NULL); /* This is an update request */ if ((first = lookup_key(c, r->key))) { if (cache_flush) { /* For unique entries drop all entries older than one second */ for (e = first; e; e = e->by_key_next) { AvahiUsec t; t = avahi_timeval_diff(&now, &e->timestamp); if (t > 1000000) expire_in_one_second(c, e, AVAHI_CACHE_REPLACE_FINAL); } } /* Look for exactly the same entry */ for (e = first; e; e = e->by_key_next) if (avahi_record_equal_no_ttl(e->record, r)) break; } if (e) { /* avahi_log_debug("found matching cache entry"); */ /* We need to update the hash table key if we replace the * record */ if (e->by_key_prev == NULL) avahi_hashmap_replace(c->hashmap, r->key, e); /* Update the record */ avahi_record_unref(e->record); e->record = avahi_record_ref(r); /* avahi_log_debug("cache: updating %s", txt); */ } else { /* No entry found, therefore we create a new one */ /* avahi_log_debug("cache: couldn't find matching cache entry for %s", txt); */ if (c->n_entries >= AVAHI_CACHE_ENTRIES_MAX) return; if (!(e = avahi_new(AvahiCacheEntry, 1))) { avahi_log_error(__FILE__": Out of memory"); return; } e->cache = c; e->time_event = NULL; e->record = avahi_record_ref(r); /* Append to hash table */ AVAHI_LLIST_PREPEND(AvahiCacheEntry, by_key, first, e); avahi_hashmap_replace(c->hashmap, e->record->key, first); /* Append to linked list */ AVAHI_LLIST_PREPEND(AvahiCacheEntry, entry, c->entries, e); c->n_entries++; /* Notify subscribers */ avahi_multicast_lookup_engine_notify(c->server->mdns.multicast_lookup_engine, c->interface, e->record, AVAHI_BROWSER_NEW); } e->origin = *a; e->timestamp = now; next_expiry(c, e, 80); e->state = AVAHI_CACHE_VALID; e->cache_flush = cache_flush; } /* avahi_free(txt); */ }