예제 #1
0
int swTimer_select(swTimer *timer)
{
    int64_t now_msec = swTimer_get_relative_msec();
    if (now_msec < 0)
    {
        return SW_ERR;
    }

    swTimer_node *tnode = NULL;
    swHeap_node *tmp;
    long timer_id;

    while ((tmp = swHeap_top(timer->heap)))
    {
        tnode = tmp->data;
        if (tnode->exec_msec > now_msec)
        {
            break;
        }

        timer_id = timer->_current_id = tnode->id;
        if (!tnode->remove)
        {
            tnode->callback(timer, tnode);
        }
        timer->_current_id = -1;

        //persistent timer
        if (tnode->interval > 0 && !tnode->remove)
        {
            while (tnode->exec_msec <= now_msec)
            {
                tnode->exec_msec += tnode->interval;
            }
            swHeap_change_priority(timer->heap, tnode->exec_msec, tmp);
            continue;
        }

        timer->num--;
        swHeap_pop(timer->heap);
        swHashMap_del_int(timer->map, timer_id);
        sw_free(tnode);
    }

    if (!tnode || !tmp)
    {
        timer->_next_msec = -1;
        timer->set(timer, -1);
    }
    else
    {
        timer->set(timer, tnode->exec_msec - now_msec);
    }
    return SW_OK;
}
예제 #2
0
파일: Timer.c 프로젝트: akrick/swoole-src
int swTimer_select(swTimer *timer)
{
    int64_t now_msec = swTimer_get_relative_msec();
    if (now_msec < 0)
    {
        return SW_ERR;
    }

    swTimer_node *tnode = NULL;
    swHeap_node *tmp;

    while ((tmp = swHeap_top(timer->heap)))
    {
        tnode = tmp->data;
        if (tnode->exec_msec > now_msec)
        {
            break;
        }
        //tick timer
        if (tnode->interval > 0)
        {
            timer->onTick(timer, tnode);
            if (!tnode->remove)
            {
                int64_t _now_msec = swTimer_get_relative_msec();
                if (_now_msec <= 0)
                {
                    tnode->exec_msec = now_msec + tnode->interval;
                }
                else if (tnode->exec_msec + tnode->interval < _now_msec)
                {
                    tnode->exec_msec = _now_msec + tnode->interval;
                }
                else
                {
                    tnode->exec_msec += tnode->interval;
                }
                swHeap_change_priority(timer->heap, tnode->exec_msec, tmp);
                continue;
            }
        }
        //after timer
        else
        {
            timer->onAfter(timer, tnode);
        }
        timer->num --;
        swHeap_pop(timer->heap);
        sw_free(tnode);
    }

    if (!tnode)
    {
        timer->_next_msec = -1;
        timer->set(timer, -1);
    }
    else
    {
        timer->set(timer, tnode->exec_msec - now_msec);
    }
    return SW_OK;
}