diff options
Diffstat (limited to 'librabbitmq/amqp_timer.c')
-rw-r--r-- | librabbitmq/amqp_timer.c | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/librabbitmq/amqp_timer.c b/librabbitmq/amqp_timer.c index 7066358..95606b8 100644 --- a/librabbitmq/amqp_timer.c +++ b/librabbitmq/amqp_timer.c @@ -20,7 +20,9 @@ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ +#include "amqp.h" #include "amqp_timer.h" +#include <string.h> #if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) # define AMQP_WIN_TIMER_API @@ -38,7 +40,7 @@ uint64_t amqp_get_monotonic_timestamp(void) { - static uint64_t NS_PER_COUNT = 0; + static double NS_PER_COUNT = 0; LARGE_INTEGER perf_count; if (0 == NS_PER_COUNT) { @@ -46,14 +48,14 @@ amqp_get_monotonic_timestamp(void) if (!QueryPerformanceFrequency(&perf_frequency)) { return 0; } - NS_PER_COUNT = AMQP_NS_PER_S / perf_frequency.QuadPart; + NS_PER_COUNT = (double)AMQP_NS_PER_S / perf_frequency.QuadPart; } if (!QueryPerformanceCounter(&perf_count)) { return 0; } - return perf_count.QuadPart * NS_PER_COUNT; + return (uint64_t)(perf_count.QuadPart * NS_PER_COUNT); } #endif /* AMQP_WIN_TIMER_API */ @@ -96,3 +98,38 @@ amqp_get_monotonic_timestamp(void) return ((uint64_t)tp.tv_sec * AMQP_NS_PER_S + (uint64_t)tp.tv_nsec); } #endif /* AMQP_POSIX_TIMER_API */ + +int +amqp_timer_update(amqp_timer_t *timer, struct timeval *timeout) +{ + if (0 == timer->current_timestamp) { + timer->current_timestamp = amqp_get_monotonic_timestamp(); + + if (0 == timer->current_timestamp) { + return AMQP_STATUS_TIMER_FAILURE; + } + + timer->timeout_timestamp = timer->current_timestamp + + (uint64_t)timeout->tv_sec * AMQP_NS_PER_S + + (uint64_t)timeout->tv_usec * AMQP_NS_PER_US; + + } else { + timer->current_timestamp = amqp_get_monotonic_timestamp(); + + if (0 == timer->current_timestamp) { + return AMQP_STATUS_TIMER_FAILURE; + } + } + + if (timer->current_timestamp > timer->timeout_timestamp) { + return AMQP_STATUS_TIMEOUT; + } + + timer->ns_until_next_timeout = timer->timeout_timestamp - timer->current_timestamp; + + memset(&timer->tv, 0, sizeof(struct timeval)); + timer->tv.tv_sec = timer->ns_until_next_timeout / AMQP_NS_PER_S; + timer->tv.tv_usec = (timer->ns_until_next_timeout % AMQP_NS_PER_S) / AMQP_NS_PER_US; + + return AMQP_STATUS_OK; +} |