about summary refs log tree commit diff
path: root/inet/net-internal.h
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2017-02-28 15:28:45 +0100
committerFlorian Weimer <fweimer@redhat.com>2017-02-28 15:36:17 +0100
commitcf0bd2f73bd65beab613865bba567d7787836888 (patch)
tree8cde5a2a9547382fac6546c9397aebbb914cb485 /inet/net-internal.h
parent37fb019cb02656d0ce0b8d40d56fe8c42f0d1658 (diff)
downloadglibc-cf0bd2f73bd65beab613865bba567d7787836888.tar.gz
glibc-cf0bd2f73bd65beab613865bba567d7787836888.tar.xz
glibc-cf0bd2f73bd65beab613865bba567d7787836888.zip
sunrpc: Improvements for UDP client timeout handling [BZ #20257]
This commit fixes various aspects in the UDP client timeout handling.
Timeouts are now applied in a more consistent fashion.  Discarded UDP
packets no longer prevent the timeout from happening at all.
Diffstat (limited to 'inet/net-internal.h')
-rw-r--r--inet/net-internal.h89
1 files changed, 89 insertions, 0 deletions
diff --git a/inet/net-internal.h b/inet/net-internal.h
index 087597ed99..2b2632c7ba 100644
--- a/inet/net-internal.h
+++ b/inet/net-internal.h
@@ -20,11 +20,100 @@
 #define _NET_INTERNAL_H 1
 
 #include <arpa/inet.h>
+#include <stdbool.h>
 #include <stdint.h>
+#include <sys/time.h>
 
 int __inet6_scopeid_pton (const struct in6_addr *address,
                           const char *scope, uint32_t *result)
   internal_function attribute_hidden;
 libc_hidden_proto (__inet6_scopeid_pton)
 
+
+/* Deadline handling for enforcing timeouts.
+
+   Code should call __deadline_current_time to obtain the current time
+   and cache it locally.  The cache needs updating after every
+   long-running or potentially blocking operation.  Deadlines relative
+   to the current time can be computed using __deadline_from_timeval.
+   The deadlines may have to be recomputed in response to certain
+   events (such as an incoming packet), but they are absolute (not
+   relative to the current time).  A timeout suitable for use with the
+   poll function can be computed from such a deadline using
+   __deadline_to_ms.
+
+   The fields in the structs defined belowed should only be used
+   within the implementation.  */
+
+/* Cache of the current time.  Used to compute deadlines from relative
+   timeouts and vice versa.  */
+struct deadline_current_time
+{
+  struct timespec current;
+};
+
+/* Return the current time.  Terminates the process if the current
+   time is not available.  */
+struct deadline_current_time __deadline_current_time (void)
+  internal_function attribute_hidden;
+
+/* Computed absolute deadline.  */
+struct deadline
+{
+  struct timespec absolute;
+};
+
+
+/* For internal use only.  */
+static inline bool
+__deadline_is_infinite (struct deadline deadline)
+{
+  return deadline.absolute.tv_nsec < 0;
+}
+
+/* Return true if the current time is at the deadline or past it.  */
+static inline bool
+__deadline_elapsed (struct deadline_current_time current,
+                    struct deadline deadline)
+{
+  return !__deadline_is_infinite (deadline)
+    && (current.current.tv_sec > deadline.absolute.tv_sec
+        || (current.current.tv_sec == deadline.absolute.tv_sec
+            && current.current.tv_nsec >= deadline.absolute.tv_nsec));
+}
+
+/* Return the deadline which occurs first.  */
+static inline struct deadline
+__deadline_first (struct deadline left, struct deadline right)
+{
+  if (__deadline_is_infinite (right)
+      || left.absolute.tv_sec < right.absolute.tv_sec
+      || (left.absolute.tv_sec == right.absolute.tv_sec
+          && left.absolute.tv_nsec < right.absolute.tv_nsec))
+    return left;
+  else
+    return right;
+}
+
+/* Add TV to the current time and return it.  Returns a special
+   infinite absolute deadline on overflow.  */
+struct deadline __deadline_from_timeval (struct deadline_current_time,
+                                         struct timeval tv)
+  internal_function attribute_hidden;
+
+/* Compute the number of milliseconds until the specified deadline,
+   from the current time in the argument.  The result is mainly for
+   use with poll.  If the deadline has already passed, return 0.  If
+   the result would overflow an int, return INT_MAX.  */
+int __deadline_to_ms (struct deadline_current_time, struct deadline)
+  internal_function attribute_hidden;
+
+/* Return true if TV.tv_sec is non-negative and TV.tv_usec is in the
+   interval [0, 999999].  */
+static inline bool
+__is_timeval_valid_timeout (struct timeval tv)
+{
+  return tv.tv_sec >= 0 && tv.tv_usec >= 0 && tv.tv_usec < 1000 * 1000;
+}
+
 #endif /* _NET_INTERNAL_H */