summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Antonuk <alan.antonuk@gmail.com>2015-06-01 22:25:00 -0700
committerAlan Antonuk <alan.antonuk@gmail.com>2015-06-01 23:50:27 -0700
commitbe2e6dd499067cc4bf6b5a28242f494a2dfef299 (patch)
tree63c599a0493c3f0a0a9ff7f6afb1edd7e72503d3
parent6f9b6183203d6a0e8a0cdaea02129449a70dfcf0 (diff)
downloadrabbitmq-c-be2e6dd499067cc4bf6b5a28242f494a2dfef299.tar.gz
Add amqp_time_tv_until() function.
-rw-r--r--librabbitmq/amqp_time.c37
-rw-r--r--librabbitmq/amqp_time.h15
2 files changed, 52 insertions, 0 deletions
diff --git a/librabbitmq/amqp_time.c b/librabbitmq/amqp_time.c
index 9bfbb16..86a992c 100644
--- a/librabbitmq/amqp_time.c
+++ b/librabbitmq/amqp_time.c
@@ -204,6 +204,43 @@ int amqp_time_ms_until(amqp_time_t time) {
return left_ms;
}
+int amqp_time_tv_until(amqp_time_t time, struct timeval *in,
+ struct timeval **out) {
+ uint64_t now_ns;
+ uint64_t delta_ns;
+
+ assert(in != NULL);
+ if (UINT64_MAX == time.time_point_ns) {
+ *out = NULL;
+ return AMQP_STATUS_OK;
+ }
+ if (0 == time.time_point_ns) {
+ in->tv_sec = 0;
+ in->tv_usec = 0;
+ *out = in;
+ return AMQP_STATUS_OK;
+ }
+
+ now_ns = amqp_get_monotonic_timestamp();
+ if (0 == now_ns) {
+ return AMQP_STATUS_TIMER_FAILURE;
+ }
+
+ if (now_ns >= time.time_point_ns) {
+ in->tv_sec = 0;
+ in->tv_usec = 0;
+ *out = in;
+ return AMQP_STATUS_OK;
+ }
+
+ delta_ns = time.time_point_ns - now_ns;
+ in->tv_sec = (int)(delta_ns / AMQP_NS_PER_S);
+ in->tv_usec = (int)((delta_ns % AMQP_NS_PER_S) / AMQP_NS_PER_US);
+ *out = in;
+
+ return AMQP_STATUS_OK;
+}
+
int amqp_time_has_past(amqp_time_t time) {
uint64_t now_ns;
if (UINT64_MAX == time.time_point_ns) {
diff --git a/librabbitmq/amqp_time.h b/librabbitmq/amqp_time.h
index 1bafd50..be939f1 100644
--- a/librabbitmq/amqp_time.h
+++ b/librabbitmq/amqp_time.h
@@ -100,6 +100,21 @@ amqp_time_t amqp_time_infinite(void);
*/
int amqp_time_ms_until(amqp_time_t time);
+/* Gets a timeval filled in with the time until amqp_time_t. Suitable for the
+ * parameter in select().
+ *
+ * The in parameter specifies a storage location for *out.
+ * If time is an inf timeout, then *out = NULL.
+ * If time is a 0-timeout or the timer has expired, then *out = {0, 0}
+ * Otherwise *out is set to the time left on the time.
+ *
+ * AMQP_STATUS_OK will be returned if successfully filled.
+ * AMQP_STATUS_TIMER_FAILURE is returned when the underlying call to get the
+ * current timestamp fails.
+ */
+int amqp_time_tv_until(amqp_time_t time, struct timeval *in,
+ struct timeval **out);
+
/* Test whether current time is past the provided time.
*
* TODO: this isn't a great interface to use. Fix this.