Пример #1
0
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;
}
Пример #2
0
AvahiUsec avahi_age(const struct timeval *a) {
    struct timeval now;
    
    assert(a);

    gettimeofday(&now, NULL);

    return avahi_timeval_diff(&now, a);
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
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;
}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
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);  */
}