Example #1
0
static void next_expiry(AvahiCache *c, AvahiCacheEntry *e, unsigned percent) {
    AvahiUsec usec, left, right;
    time_t now;

    assert(c);
    assert(e);
    assert(percent > 0 && percent <= 100);

    usec = (AvahiUsec) e->record->ttl * 10000;

    left = usec * percent;
    right = usec * (percent+2); /* 2% jitter */

    now = time(NULL);

    if (now >= c->last_rand_timestamp + 10) {
        c->last_rand = rand();
        c->last_rand_timestamp = now;
    }

    usec = left + (AvahiUsec) ((double) (right-left) * c->last_rand / (RAND_MAX+1.0));

    e->expiry = e->timestamp;
    avahi_timeval_add(&e->expiry, usec);

/*     g_message("wake up in +%lu seconds", e->expiry.tv_sec - e->timestamp.tv_sec); */

    update_time_event(c, e);
}
Example #2
0
static void expire_in_one_second(AvahiCache *c, AvahiCacheEntry *e, AvahiCacheEntryState state) {
    assert(c);
    assert(e);

    e->state = state;
    gettimeofday(&e->expiry, NULL);
    avahi_timeval_add(&e->expiry, 1000000); /* 1s */
    update_time_event(c, e);
}
Example #3
0
static void add_to_cache(AvahiWideAreaLookupEngine *e, AvahiRecord *r) {
    AvahiWideAreaCacheEntry *c;
    int is_new;
    
    assert(e);
    assert(r);

    if ((c = find_record_in_cache(e, r))) {
        is_new = 0;

        /* Update the existing entry */
        avahi_record_unref(c->record);
    } else {
        AvahiWideAreaCacheEntry *t;

        is_new = 1;

        /* Enforce cache size */
        if (e->cache_n_entries >= CACHE_ENTRIES_MAX)
            /* Eventually we should improve the caching algorithm here */
            goto finish;
        
        c = avahi_new(AvahiWideAreaCacheEntry, 1);
        c->engine = e;
        c->time_event = NULL;

        AVAHI_LLIST_PREPEND(AvahiWideAreaCacheEntry, cache, e->cache, c);

        /* Add the new entry to the cache entry hash table */
        t = avahi_hashmap_lookup(e->cache_by_key, r->key);
        AVAHI_LLIST_PREPEND(AvahiWideAreaCacheEntry, by_key, t, c);
        avahi_hashmap_replace(e->cache_by_key, avahi_key_ref(r->key), t);

        e->cache_n_entries ++;
    }

    c->record = avahi_record_ref(r);
    
    gettimeofday(&c->timestamp, NULL);
    c->expiry = c->timestamp;
    avahi_timeval_add(&c->expiry, r->ttl * 1000000);

    if (c->time_event)
        avahi_time_event_update(c->time_event, &c->expiry);
    else
        c->time_event = avahi_time_event_new(e->server->time_event_queue, &c->expiry, expiry_event, c);

finish:
    
    if (is_new)
        run_callbacks(e, r);
}
Example #4
0
struct timeval *avahi_elapse_time(struct timeval *tv, unsigned msec, unsigned jitter) {
    assert(tv);

    gettimeofday(tv, NULL);

    if (msec)
        avahi_timeval_add(tv, (AvahiUsec) msec*1000);

    if (jitter) {
        static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
        static int last_rand;
        static time_t timestamp = 0;

        time_t now;
        int r;
        
        now = time(NULL);

        pthread_mutex_lock(&mutex);
        if (now >= timestamp + 10) {
            timestamp = now;
            last_rand = rand();
        }
        
        r = last_rand;
        
        pthread_mutex_unlock(&mutex);

        /* We use the same jitter for 10 seconds. That way our
         * time events elapse in bursts which has the advantage that
         * packet data can be aggregated better */
        
        avahi_timeval_add(tv, (AvahiUsec) (jitter*1000.0*r/(RAND_MAX+1.0)));
    }
        
    return tv;
}
Example #5
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;
}
int avahi_s_entry_group_commit(AvahiSEntryGroup *g) {
    struct timeval now;
    
    assert(g);
    assert(!g->dead);

    if (g->state != AVAHI_ENTRY_GROUP_UNCOMMITED && g->state != AVAHI_ENTRY_GROUP_COLLISION)
        return avahi_server_set_errno(g->server, AVAHI_ERR_BAD_STATE);

    if (avahi_s_entry_group_is_empty(g))
        return avahi_server_set_errno(g->server, AVAHI_ERR_IS_EMPTY);

    g->n_register_try++;

    avahi_timeval_add(&g->register_time,
                      1000*(g->n_register_try >= AVAHI_RR_RATE_LIMIT_COUNT ?
                            AVAHI_RR_HOLDOFF_MSEC_RATE_LIMIT :
                            AVAHI_RR_HOLDOFF_MSEC));

    gettimeofday(&now, NULL);

    if (avahi_timeval_compare(&g->register_time, &now) <= 0) {

        /* Holdoff time passed, so let's start probing */
        entry_group_commit_real(g);
    } else {

         /* Holdoff time has not yet passed, so let's wait */
        assert(!g->register_time_event);
        g->register_time_event = avahi_time_event_new(g->server->time_event_queue, &g->register_time, entry_group_register_time_event_callback, g);
        
        avahi_s_entry_group_change_state(g, AVAHI_ENTRY_GROUP_REGISTERING);
    }

    return AVAHI_OK;
}