#include "complib/cl_timer.h"\r
\r
\r
+static HANDLE\r
+__clear_timer_handle(\r
+ IN cl_timer_t* const p_timer )\r
+{\r
+ HANDLE timer;\r
+\r
+ EnterCriticalSection( &p_timer->lock );\r
+ timer = p_timer->h_timer;\r
+ p_timer->h_timer = NULL;\r
+ LeaveCriticalSection( &p_timer->lock );\r
+\r
+ return timer;\r
+}\r
+\r
static void CALLBACK\r
__timer_callback( \r
IN cl_timer_t* const p_timer,\r
IN BOOLEAN timer_signalled )\r
{\r
- /* timer_signalled is always TRUE, and has no value. */\r
- CL_ASSERT( timer_signalled );\r
- UNUSED_PARAM( timer_signalled );\r
+ UNUSED_PARAMETER( timer_signalled );\r
\r
- p_timer->timeout_time = 0;\r
- p_timer->thread_id = GetCurrentThreadId();\r
+ if( !__clear_timer_handle( p_timer ))\r
+ return;\r
\r
+ EnterCriticalSection( &p_timer->cb_lock );\r
(p_timer->pfn_callback)( (void*)p_timer->context );\r
-\r
- p_timer->thread_id = 0;\r
+ LeaveCriticalSection( &p_timer->cb_lock );\r
}\r
\r
\r
cl_timer_construct(\r
IN cl_timer_t* const p_timer )\r
{\r
- p_timer->h_timer = NULL;\r
- p_timer->timeout_time = 0;\r
- p_timer->thread_id = 0;\r
+ memset(p_timer, 0, sizeof *p_timer);\r
}\r
\r
\r
\r
p_timer->pfn_callback = pfn_callback;\r
p_timer->context = context;\r
+ p_timer->h_timer_queue = CreateTimerQueue();\r
+ if( !p_timer->h_timer_queue )\r
+ return CL_ERROR;\r
+\r
+ InitializeCriticalSection( &p_timer->lock );\r
+ InitializeCriticalSection( &p_timer->cb_lock );\r
return( CL_SUCCESS );\r
}\r
\r
{\r
CL_ASSERT( p_timer );\r
\r
- cl_timer_stop( p_timer );\r
+ if( p_timer->h_timer_queue )\r
+ {\r
+ DeleteTimerQueueEx( p_timer->h_timer_queue, INVALID_HANDLE_VALUE );\r
+ DeleteCriticalSection( &p_timer->lock );\r
+ DeleteCriticalSection( &p_timer->cb_lock );\r
+ }\r
}\r
\r
\r
IN cl_timer_t* const p_timer,\r
IN const uint32_t time_ms )\r
{\r
- CL_ASSERT( p_timer );\r
-\r
- cl_timer_stop( p_timer );\r
-\r
- p_timer->timeout_time = cl_get_time_stamp() + (((uint64_t)time_ms) * 1000);\r
-\r
- if( !CreateTimerQueueTimer( &p_timer->h_timer, NULL, __timer_callback,\r
- p_timer, time_ms, 0, WT_EXECUTEINIOTHREAD ) )\r
- {\r
- return( CL_ERROR );\r
- }\r
- \r
- return( CL_SUCCESS );\r
+ return cl_timer_trim( p_timer, time_ms );\r
}\r
\r
\r
IN cl_timer_t* const p_timer,\r
IN const uint32_t time_ms )\r
{\r
- uint64_t timeout_time;\r
+ uint64_t timeout;\r
+ cl_status_t status = CL_SUCCESS;\r
\r
CL_ASSERT( p_timer );\r
CL_ASSERT( p_timer->pfn_callback );\r
\r
- /* Calculate the timeout time in the timer object. */\r
- timeout_time = cl_get_time_stamp() + (((uint64_t)time_ms) * 1000);\r
-\r
- /* Only pull in the timeout time. */\r
- if( p_timer->timeout_time && p_timer->timeout_time < timeout_time )\r
- return( CL_SUCCESS );\r
+ timeout = cl_get_time_stamp() + (((uint64_t)time_ms) * 1000);\r
\r
- return cl_timer_start( p_timer, time_ms );\r
+ EnterCriticalSection( &p_timer->lock );\r
+ if ( !p_timer->h_timer || timeout < p_timer->timeout_time )\r
+ {\r
+ if( p_timer->h_timer )\r
+ DeleteTimerQueueTimer( p_timer->timer_queue, timer, NULL );\r
+\r
+ p_timer->timeout_time = timeout;\r
+ if( !CreateTimerQueueTimer( &p_timer->h_timer, p_timer->h_timer_queue,\r
+ __timer_callback, p_timer, time_ms, 0, WT_EXECUTEINIOTHREAD ) )\r
+ {\r
+ p_timer->h_timer = NULL;\r
+ status = CL_ERROR;\r
+ }\r
+ }\r
+ LeaveCriticalSection( &p_timer->lock );\r
+ return status;\r
}\r
\r
\r
cl_timer_stop(\r
IN cl_timer_t* const p_timer )\r
{\r
+ HANDLE timer;\r
+\r
CL_ASSERT( p_timer );\r
\r
- if( p_timer->h_timer && p_timer->thread_id != GetCurrentThreadId() )\r
- {\r
- /* Make sure we block until the timer is cancelled. */\r
- DeleteTimerQueueTimer( NULL, p_timer->h_timer, INVALID_HANDLE_VALUE );\r
- p_timer->h_timer = NULL;\r
- }\r
- p_timer->timeout_time = 0;\r
+ timer = __clear_timer_handle( p_timer );\r
+\r
+ if( timer )\r
+ DeleteTimerQueueTimer( p_timer->timer_queue, timer, INVALID_HANDLE_VALUE );\r
}\r
\r
\r