⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rvtimer.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 4 页
字号:
    maxtimers = RvObjPoolGetMaxitems(&tqueue->pool);
    RvLockRelease(&tqueue->lock);

    return maxtimers;
}

/* Sets the value for maxtimers (not used by FIXED queues). */
/* Returns RV_TRUE upon success (otherwise RV_FALSE). */
RvBool RvTimerQueueSetMaxtimers(RvTimerQueue *tqueue, RvSize_t maxtimers)
{
    RvBool result;

#if defined(RV_NULLCHECK)
    if(tqueue == NULL)
        return RV_FALSE;
#endif

    if(RvLockGet(&tqueue->lock) != RV_OK)
        return RV_FALSE;
    result = RvObjPoolSetMaxitems(&tqueue->pool, maxtimers);
    RvLockRelease(&tqueue->lock);

    return result;
}

/* Changes the value for maxtimers (not used by FIXED queues) by an */
/* offset (delta). The direction parameter indicates whether the delta */
/* is an increase or a decrease. Returns RV_TRUE upon success */
/* (otherwise RV_FALSE). */
RvBool RvTimerQueueChangeMaxtimers(RvTimerQueue *tqueue, RvSize_t delta, RvBool direction)
{
    RvBool result;
    RvSize_t maxtimers;

#if defined(RV_NULLCHECK)
    if(tqueue == NULL)
        return RV_FALSE;
#endif
#if defined(RV_RANGECHECK)
    if((direction != RV_TIMER_VALUE_INCREASE) && (direction != RV_TIMER_VALUE_DECREASE))
        return RV_FALSE;
#endif

    if(RvLockGet(&tqueue->lock) != RV_OK)
        return RV_FALSE;
    maxtimers = RvObjPoolGetMaxitems(&tqueue->pool);
    if(direction == RV_TIMER_VALUE_DECREASE) {
        if(delta > maxtimers) {
            /* Can't go negative. */
            RvLockRelease(&tqueue->lock);
            return RV_FALSE;
        }
        maxtimers -= delta;
    } else maxtimers += delta;
    result = RvObjPoolSetMaxitems(&tqueue->pool, maxtimers);
    RvLockRelease(&tqueue->lock);

    return result;
}

/* Returns current value for mintimers (not used by FIXED). */
RvSize_t RvTimerQueueGetMintimers(RvTimerQueue *tqueue)
{
    RvSize_t mintimers;

#if defined(RV_NULLCHECK)
    if(tqueue == NULL)
        return 0;
#endif

    if(RvLockGet(&tqueue->lock) != RV_OK)
        return 0;
    mintimers = RvObjPoolGetMinitems(&tqueue->pool);
    RvLockRelease(&tqueue->lock);

    return mintimers;
}

/* Sets the value for mintimers. Returns RV_TRUE upon success */
/* (otherwise RV_FALSE). Note: for FIXED timer queues mintimers */
/* is not normally used and increasing mintimers above the current */
/* timer queue size will increase the memory used by the pool but will */
/* NOT increase the size of the timer queue. Use RvTimerQueueSetSize */
/* to change the size of a FIXED timer queue. */
RvBool RvTimerQueueSetMintimers(RvTimerQueue *tqueue, RvSize_t mintimers)
{
    RvBool result;

#if defined(RV_NULLCHECK)
    if(tqueue == NULL)
        return RV_FALSE;
#endif

    if(RvLockGet(&tqueue->lock) != RV_OK)
        return RV_FALSE;
    result = RvObjPoolSetMinitems(&tqueue->pool, mintimers);
    RvLockRelease(&tqueue->lock);

    return result;
}

/* Changes the value for mintimers by an offset (delta). The */
/* direction parameter indicates whether the delta is an increase */
/* or a decrease. Returns RV_TRUE upon success (otherwise RV_FALSE). */
/* See RvTimerQueueSetMintimers note about increasing FIXED timer queues. */
RvBool RvTimerQueueChangeMintimers(RvTimerQueue *tqueue, RvSize_t delta, RvBool direction)
{
    RvBool result;
    RvSize_t mintimers;

#if defined(RV_NULLCHECK)
    if(tqueue == NULL)
        return RV_FALSE;
#endif
#if defined(RV_RANGECHECK)
    if((direction != RV_TIMER_VALUE_INCREASE) && (direction != RV_TIMER_VALUE_DECREASE))
        return RV_FALSE;
#endif

    if(RvLockGet(&tqueue->lock) != RV_OK)
        return RV_FALSE;
    mintimers = RvObjPoolGetMinitems(&tqueue->pool);
    if(direction == RV_TIMER_VALUE_DECREASE) {
        if(delta > mintimers) {
            /* Can't go negative. */
            RvLockRelease(&tqueue->lock);
            return RV_FALSE;
        }
        mintimers -= delta;
    } else mintimers += delta;
    result = RvObjPoolSetMinitems(&tqueue->pool, mintimers);
    RvLockRelease(&tqueue->lock);

    return result;
}

/* Returns current value for freelevel (only used by DYNAMIC queues) */
RvSize_t RvTimerQueueGetFreelevel(RvTimerQueue *tqueue)
{
    RvSize_t freelevel;

#if defined(RV_NULLCHECK)
    if(tqueue == NULL)
        return 0;
#endif

    if(RvLockGet(&tqueue->lock) != RV_OK)
        return 0;
    freelevel = RvObjPoolGetFreelevel(&tqueue->pool);
    RvLockRelease(&tqueue->lock);

    return freelevel;
}

/* Sets new value for freelevel. Return RV_TRUE if successful (otherwise */
/* return RV_FALSE). Use only by DYNAMIC queues. */
RvBool RvTimerQueueSetFreelevel(RvTimerQueue *tqueue, RvSize_t freelevel)
{
    RvBool result;

#if defined(RV_NULLCHECK)
    if(tqueue == NULL)
        return RV_FALSE;
#endif

    if(RvLockGet(&tqueue->lock) != RV_OK)
        return RV_FALSE;
    result = RvObjPoolSetFreelevel(&tqueue->pool, freelevel);
    RvLockRelease(&tqueue->lock);

    return result;
}

/* Returns number of nanoseconds until next event in nextevent */
/* parameter. Negative number indicates that the event is overdue. */
/* If the queue is empty a warning is returned and nextevent is untouched. */
RVCOREAPI RvStatus RVCALLCONV RvTimerQueueNextEvent(RvTimerQueue *tqueue, RvInt64 *nextevent)
{
    RvStatus result;
    RvInt64 curtime;
    RvTimerEvent *event;

#if defined(RV_NULLCHECK)
    if(tqueue == NULL)
        return RvTimerErrorCode(RV_ERROR_NULLPTR);
#endif

    curtime = RvTimestampGet();

    result = RvLockGet(&tqueue->lock);
    if(result != RV_OK)
        return result;

    event = (RvTimerEvent *)RvPQueuePeek(&tqueue->pqueue);
    if(event != NULL) {
        *nextevent = event->triggertime - curtime;
    } else result = RvTimerErrorCode(RV_TIMER_WARNING_QUEUEEMPTY);

    RvLockRelease(&tqueue->lock);
    return result;
}

/* Destruct a timer queue. This must only be called by a single task */
/* and no calls to any timer function should be in progress. */
RVCOREAPI RvStatus RVCALLCONV RvTimerQueueDestruct(RvTimerQueue *tqueue)
{
    RvStatus result;
    RvTimerEvent *event;

#if defined(RV_NULLCHECK)
    if(tqueue == NULL)
        return RvTimerErrorCode(RV_ERROR_NULLPTR);
#endif

    RvTimerQueueStop(tqueue); /* Doesn't hurt to make sure. */

    result = RvLockGet(&tqueue->lock);
    if(result != RV_OK)
        return result;

    /* Return all events back to pool. */
    for(;;) {
        event = (RvTimerEvent *)RvPQueueGet(&tqueue->pqueue);
        if(event == NULL)
            break;
        RvObjPoolReleaseItem(&tqueue->pool, event);
    }

    RvPQueueDestruct(&tqueue->pqueue);
    if(RvObjPoolDestruct(&tqueue->pool) != RV_TRUE)
        result = RvTimerErrorCode(RV_TIMER_ERROR_POOL);
    RvSemaphoreDestruct(&tqueue->wait);
    RvLockDestruct(&tqueue->lock);

    return result;
}

/* Create individual event for pool. */
static void *RvTimerEventConstruct(void *objptr, void *data)
{
    RvStatus status;
    RvTimerEvent *timerevent;

    timerevent = (RvTimerEvent *)objptr;
    status = RvSemaphoreConstruct(&timerevent->wait, 0);
    if(status != RV_OK)
        return NULL;
    timerevent->waitcount = 0; /* Should always stay in sync with semaphore */
    timerevent->tqueue = (RvTimerQueue *)data; /* Never changes. */
    return objptr;
}

/* Destroy individual event for pool. */
static void RvTimerEventDestruct(void *objptr, void *data)
{
    RV_UNUSED_ARG(data);
    RvSemaphoreDestruct(&((RvTimerEvent *)objptr)->wait);
}

/* Allocate memory page for event pool and Priority Queue. */
static void *RvTimerMemAlloc(RvSize_t size, void *data)
{
    void *result;
    RvStatus status;

    status = RvMemoryAlloc((RvMemory *)data, &result, size);
    if(status != RV_OK)
        return NULL;
    return result;
}

/* Free memory page for event pool and Priority Queue. */
static void RvTimerMemFree(void *ptr, void *data)
{
    RV_UNUSED_ARG(data);
    RvMemoryFree(ptr);
}

/* For Priority queue, return RV_TRUE if ptr1 higher priority than ptr2. */
static RvBool RvTimerPQueueItemCmp(void *ptr1, void *ptr2)
{
    if(((RvTimerEvent *)ptr1)->triggertime < ((RvTimerEvent *)ptr2)->triggertime)
        return RV_TRUE;
    return RV_FALSE;
}

/* For Priority Queue, save index of specified item (used for deletion). */
static void RvTimerPQueueNewIndex(void *item, RvSize_t index)
{
    ((RvTimerEvent *)item)->index = index;
}

/* Add an event to the timer queue specified by tqueue. The timertype is ONESHOT or PERIODIC and */
/* delay specificies the number of nanoseconds to delay before triggering the callback function. */
/* The userdata is simply passed to the callback function. Upon successfull completion of RvTimerStart, */
/* the timer structure will contain an identifier which can be used to cancel that timer. There is */
/* no construct or destruct on the timer structure and it is not required to be maintained for */
/* the event to occur. It is only used for cancelling the timer. If it is NULL, then the timer can */
/* not be cancelled. Note: The minimum time for a timer and the resolution is based on the */
/* timestamp driver and on the rate at which the timer queue is checked. */
RVCOREAPI RvStatus RVCALLCONV RvTimerStart(RvTimer *timer, RvTimerQueue *tqueue, RvInt timertype, RvInt64 delay, RvTimerFunc callback, void *userdata)
{
    RvStatus result;
    RvInt64 starttime;
    RvTimerEvent *event;

#if defined(RV_NULLCHECK)
    if((tqueue == NULL) || (callback == NULL))
        return RvTimerErrorCode(RV_ERROR_NULLPTR);
#endif
#if defined(RV_RANGECHECK)
    if((timertype != RV_TIMER_TYPE_ONESHOT) && (timertype != RV_TIMER_TYPE_PERIODIC))
        return RvTimerErrorCode(RV_ERROR_OUTOFRANGE);
#endif

    /* Get start time as soon as possible for best accuracy. */
    starttime = RvTimestampGet();

    result = RvLockGet(&tqueue->lock);
    if(result != RV_OK)
        return result;

    /* Get a timer event from the pool. */
    event = (RvTimerEvent *)RvObjPoolGetItem(&tqueue->pool);
    if(event == NULL) {
        RvLockRelease(&tqueue->lock);
        return RvTimerErrorCode(RV_TIMER_ERROR_QUEUEFULL);
    }

    /* Initialize event; tqueue, the wait semaphore, and waitcount are already set. */
    event->timertype = timertype;
    event->state = RV_TIMER_EVENTSTATE_QUEUED;
    tqueue->idcounter += RvUintConst(1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -