コード例 #1
0
ファイル: glib-watch.c プロジェクト: Antares84/asuswrt-merlin
static gboolean dispatch_func(GSource *source, AVAHI_GCC_UNUSED GSourceFunc callback, AVAHI_GCC_UNUSED gpointer userdata) {
    AvahiGLibPoll* g = (AvahiGLibPoll*) source;
    AvahiWatch *w;
    AvahiTimeout *next_timeout;

    g_assert(g);

    if ((next_timeout = find_next_timeout(g))) {
        GTimeVal now;
        struct timeval tvnow;
        g_source_get_current_time(source, &now);
        tvnow.tv_sec = now.tv_sec;
        tvnow.tv_usec = now.tv_usec;

        if (avahi_timeval_compare(&next_timeout->expiry, &tvnow) < 0) {
            start_timeout_callback(next_timeout);
            return TRUE;
        }
    }

    for (w = g->watches; w; w = w->watches_next)
        if (w->pollfd.revents > 0) {
            assert(w->callback);
            w->callback(w, w->pollfd.fd, map_events_from_glib(w->pollfd.revents), w->userdata);
            w->pollfd.revents = 0;
            return TRUE;
        }

    return TRUE;
}
コード例 #2
0
ファイル: glib-watch.c プロジェクト: Antares84/asuswrt-merlin
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;
}
コード例 #3
0
ファイル: time.c プロジェクト: AugHu/otp
ErtsMonotonicTime
erts_check_next_timeout_time(ErtsSchedulerData *esdp)
{
    ErtsTimerWheel *tiw = esdp->timer_wheel;
    if (tiw->true_next_timeout_time)
	return tiw->next_timeout_time;
    return find_next_timeout(esdp, tiw, 1, 0, 0);
}
コード例 #4
0
int avahi_simple_poll_dispatch(AvahiSimplePoll *s) {
    AvahiTimeout *next_timeout;
    AvahiWatch *w;

    assert(s);
    assert(s->state == STATE_RAN);
    s->state = STATE_DISPATCHING;

    /* We execute only on callback in every iteration */

    /* Check whether the wakeup time has been reached now */
    if ((next_timeout = find_next_timeout(s))) {

        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_callback(next_timeout);
            goto finish;
        }

        if (avahi_age(&next_timeout->expiry) >= 0) {

            /* Timeout elapsed */
            timeout_callback(next_timeout);
            goto finish;
        }
    }

    /* Look for some kind of I/O event */
    for (w = s->watches; w; w = w->watches_next) {

        if (w->dead)
            continue;

        assert(w->idx >= 0);
        assert(w->idx < s->n_pollfds);

        if (s->pollfds[w->idx].revents != 0) {
            w->callback(w, w->pollfd.fd, s->pollfds[w->idx].revents, w->userdata);
            goto finish;
        }
    }

finish:

    s->state = STATE_DISPATCHED;
    return 0;
}
コード例 #5
0
ファイル: main.cpp プロジェクト: CCJY/coliru
void timer_thread()
{
    while (!isCancelled) {
        std::unique_lock<std::mutex> lock(m);
        std::chrono::system_clock::time_point now;
        while (keys.empty() || earliest > (now = std::chrono::system_clock::now())) {
            if (keys.empty()) {
                cv.wait(lock);
            } else {
                cv.wait_until(lock, earliest);
            }

            if (isCancelled)
                return;
        }

        std::vector<int> expired = remove_expired(now);
        earliest = find_next_timeout();
        lock.unlock();
        std::for_each(expired.begin(), expired.end(), callback);
    }
}
コード例 #6
0
ファイル: glib-watch.c プロジェクト: Antares84/asuswrt-merlin
static gboolean check_func(GSource *source) {
    AvahiGLibPoll *g = (AvahiGLibPoll*) source;
    AvahiWatch *w;
    AvahiTimeout *next_timeout;

    g_assert(g);

    if ((next_timeout = find_next_timeout(g))) {
        GTimeVal now;
        struct timeval tvnow;
        g_source_get_current_time(source, &now);
        tvnow.tv_sec = now.tv_sec;
        tvnow.tv_usec = now.tv_usec;

        if (avahi_timeval_compare(&next_timeout->expiry, &tvnow) <= 0)
            return TRUE;
    }

    for (w = g->watches; w; w = w->watches_next)
        if (w->pollfd.revents > 0)
            return TRUE;

    return FALSE;
}
コード例 #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
ファイル: time.c プロジェクト: AugHu/otp
void
erts_bump_timers(ErtsTimerWheel *tiw, ErtsMonotonicTime curr_time)
{
    int tiw_pos_ix, slots, yielded_slot_restarted, yield_count;
    ErtsMonotonicTime bump_to, tmp_slots, old_pos;

    yield_count = ERTS_TWHEEL_BUMP_YIELD_LIMIT;

    /*
     * In order to be fair we always continue with work
     * where we left off when restarting after a yield.
     */

    if (tiw->yield_slot >= 0) {
	yielded_slot_restarted = 1;
	tiw_pos_ix = tiw->yield_slot;
	slots = tiw->yield_slots_left;
	bump_to = tiw->pos;
	old_pos = tiw->yield_start_pos;
	goto restart_yielded_slot;
    }

    do {

	yielded_slot_restarted = 0;

	bump_to = ERTS_MONOTONIC_TO_CLKTCKS(curr_time);

	while (1) {
	    ErtsTWheelTimer *p;

	    old_pos = tiw->pos;

	    if (tiw->nto == 0) {
	    empty_wheel:
		ERTS_DBG_CHK_SAFE_TO_SKIP_TO(tiw, bump_to);
		tiw->true_next_timeout_time = 0;
		tiw->next_timeout_time = curr_time + ERTS_MONOTONIC_DAY;
		tiw->pos = bump_to;
		tiw->yield_slot = ERTS_TWHEEL_SLOT_INACTIVE;
		return;
	    }

	    p = tiw->at_once.head;
	    while (p) {
		if (--yield_count <= 0) {
		    ERTS_TW_ASSERT(tiw->nto > 0);
		    ERTS_TW_ASSERT(tiw->at_once.nto > 0);
		    tiw->yield_slot = ERTS_TWHEEL_SLOT_AT_ONCE;
		    tiw->true_next_timeout_time = 1;
		    tiw->next_timeout_time = ERTS_CLKTCKS_TO_MONOTONIC(old_pos);
		    return;
		}

		ERTS_TW_ASSERT(tiw->nto > 0);
		ERTS_TW_ASSERT(tiw->at_once.nto > 0);
		tiw->nto--;
		tiw->at_once.nto--;
		tiw->at_once.head = p->next;
		if (p->next)
		    p->next->prev = NULL;
		else
		    tiw->at_once.tail = NULL;

		timeout_timer(p);

		p = tiw->at_once.head;
	    }

	    if (tiw->pos >= bump_to)
		break;

	    if (tiw->nto == 0)
		goto empty_wheel;

	    if (tiw->true_next_timeout_time) {
		ErtsMonotonicTime skip_until_pos;
		/*
		 * No need inspecting slots where we know no timeouts
		 * to trigger should reside.
		 */

		skip_until_pos = ERTS_MONOTONIC_TO_CLKTCKS(tiw->next_timeout_time);
		if (skip_until_pos > bump_to)
		    skip_until_pos = bump_to;

		skip_until_pos--;

		if (skip_until_pos > tiw->pos) {
		    ERTS_DBG_CHK_SAFE_TO_SKIP_TO(tiw, skip_until_pos);

		    tiw->pos = skip_until_pos;
		}
	    }

	    tiw_pos_ix = (int) ((tiw->pos+1) & (ERTS_TIW_SIZE-1));
	    tmp_slots = (bump_to - tiw->pos);
	    if (tmp_slots < (ErtsMonotonicTime) ERTS_TIW_SIZE)
		slots = (int) tmp_slots;
	    else
		slots = ERTS_TIW_SIZE;

	    tiw->pos = bump_to;

	    while (slots > 0) {

		p = tiw->w[tiw_pos_ix];
		if (p) {
		    if (p->next == p) {
			ERTS_TW_ASSERT(tiw->sentinel.next == &tiw->sentinel);
			ERTS_TW_ASSERT(tiw->sentinel.prev == &tiw->sentinel);
		    }
		    else {
			tiw->sentinel.next = p->next;
			tiw->sentinel.prev = p->prev;
			tiw->sentinel.next->prev = &tiw->sentinel;
			tiw->sentinel.prev->next = &tiw->sentinel;
		    }
		    tiw->w[tiw_pos_ix] = NULL;

		    while (1) {

			if (p->timeout_pos > bump_to) {
			    /* Very unusual case... */
			    ++yield_count;
			    insert_timer_into_slot(tiw, tiw_pos_ix, p);
			}
			else {
			    /* Normal case... */
			    timeout_timer(p);
			    tiw->nto--;
			}

		    restart_yielded_slot:

			p = tiw->sentinel.next;
			if (p == &tiw->sentinel) {
			    ERTS_TW_ASSERT(tiw->sentinel.prev == &tiw->sentinel);
			    break;
			}

			if (--yield_count <= 0) {
			    tiw->true_next_timeout_time = 1;
			    tiw->next_timeout_time = ERTS_CLKTCKS_TO_MONOTONIC(old_pos);
			    tiw->yield_slot = tiw_pos_ix;
			    tiw->yield_slots_left = slots;
			    tiw->yield_start_pos = old_pos;
			    return; /* Yield! */
			}

			tiw->sentinel.next = p->next;
			p->next->prev = &tiw->sentinel;
		    }
		}
		tiw_pos_ix++;
		if (tiw_pos_ix == ERTS_TIW_SIZE)
		    tiw_pos_ix = 0;
		slots--;
	    }
	}

    } while (yielded_slot_restarted);

    tiw->yield_slot = ERTS_TWHEEL_SLOT_INACTIVE;
    tiw->true_next_timeout_time = 0;
    tiw->next_timeout_time = curr_time + ERTS_MONOTONIC_DAY;

    /* Search at most two seconds ahead... */
    (void) find_next_timeout(NULL, tiw, 0, curr_time, ERTS_SEC_TO_MONOTONIC(2));
}