BOOL ChangeTimerQueueTimer(HANDLE TimerQueue, HANDLE Timer, ULONG DueTime, ULONG Period) { struct timespec CurrentTime; WINPR_TIMER_QUEUE* timerQueue; WINPR_TIMER_QUEUE_TIMER* timer; if (!TimerQueue || !Timer) return FALSE; timespec_gettimeofday(&CurrentTime); timerQueue = (WINPR_TIMER_QUEUE*) TimerQueue; timer = (WINPR_TIMER_QUEUE_TIMER*) Timer; pthread_mutex_lock(&(timerQueue->cond_mutex)); RemoveTimerQueueTimer(&(timerQueue->activeHead), timer); RemoveTimerQueueTimer(&(timerQueue->inactiveHead), timer); timer->DueTime = DueTime; timer->Period = Period; timer->next = NULL; timespec_copy(&(timer->StartTime), &CurrentTime); timespec_add_ms(&(timer->StartTime), DueTime); timespec_copy(&(timer->ExpirationTime), &(timer->StartTime)); InsertTimerQueueTimer(&(timerQueue->activeHead), timer); pthread_cond_signal(&(timerQueue->cond)); pthread_mutex_unlock(&(timerQueue->cond_mutex)); return TRUE; }
BOOL DeleteTimerQueueTimer(HANDLE TimerQueue, HANDLE Timer, HANDLE CompletionEvent) { WINPR_TIMER_QUEUE* timerQueue; WINPR_TIMER_QUEUE_TIMER* timer; if (!TimerQueue || !Timer) return FALSE; timerQueue = (WINPR_TIMER_QUEUE*) TimerQueue; timer = (WINPR_TIMER_QUEUE_TIMER*) Timer; pthread_mutex_lock(&(timerQueue->cond_mutex)); if (CompletionEvent == INVALID_HANDLE_VALUE) { /* Wait for all callback functions to complete before returning */ } else { /* Cancel timer and return immediately */ RemoveTimerQueueTimer(&(timerQueue->activeHead), timer); } pthread_cond_signal(&(timerQueue->cond)); pthread_mutex_unlock(&(timerQueue->cond_mutex)); free(timer); if (CompletionEvent && (CompletionEvent != INVALID_HANDLE_VALUE)) SetEvent(CompletionEvent); return TRUE; }
BOOL DeleteTimerQueueTimer(HANDLE TimerQueue, HANDLE Timer, HANDLE CompletionEvent) { WINPR_TIMER_QUEUE* timerQueue; WINPR_TIMER_QUEUE_TIMER* timer; if (!TimerQueue || !Timer) return FALSE; timerQueue = (WINPR_TIMER_QUEUE*) TimerQueue; timer = (WINPR_TIMER_QUEUE_TIMER*) Timer; pthread_mutex_lock(&(timerQueue->cond_mutex)); /** * Quote from MSDN regarding CompletionEvent: * If this parameter is INVALID_HANDLE_VALUE, the function waits for * all callback functions to complete before returning. * If this parameter is NULL, the function marks the timer for * deletion and returns immediately. * * Note: The current WinPR implementation implicitly waits for any * callback functions to complete (see cond_mutex usage) */ RemoveTimerQueueTimer(&(timerQueue->activeHead), timer); pthread_cond_signal(&(timerQueue->cond)); pthread_mutex_unlock(&(timerQueue->cond_mutex)); free(timer); if (CompletionEvent && (CompletionEvent != INVALID_HANDLE_VALUE)) SetEvent(CompletionEvent); return TRUE; }