connection: switch to absolute timeouts (API break)
authorDaniel Mack <daniel@zonque.org>
Tue, 21 Oct 2014 18:23:07 +0000 (20:23 +0200)
committerDaniel Mack <daniel@zonque.org>
Tue, 21 Oct 2014 20:13:25 +0000 (22:13 +0200)
Make the timeouts in struct kdbus_msg.timeout_ns absolute.

This is necessary in order to support blocking sync calls with
SA_RESTART behavior.

Signed-off-by: Daniel Mack <daniel@zonque.org>
connection.c
kdbus.h
kdbus.txt
test/kdbus-util.c

index 9317391df6d978a85d362262408983b70d500911..b0876958083738767dc58ff208f756bf1856d79c 100644 (file)
@@ -653,7 +653,7 @@ static int kdbus_conn_wait_reply(struct kdbus_ep *ep,
                                 struct kdbus_conn *conn_dst,
                                 struct kdbus_msg *msg,
                                 struct kdbus_conn_reply *reply_wait,
-                                u64 timeout_us)
+                                u64 timeout_ns)
 {
        struct kdbus_queue_entry *entry;
        int r, ret;
@@ -665,7 +665,7 @@ static int kdbus_conn_wait_reply(struct kdbus_ep *ep,
         */
        r = wait_event_interruptible_timeout(reply_wait->conn->wait,
                !reply_wait->waiting || !kdbus_conn_active(conn_src),
-               usecs_to_jiffies(timeout_us));
+               nsecs_to_jiffies(timeout_ns));
        if (r == 0)
                ret = -ETIMEDOUT;
        else if (r < 0)
@@ -859,10 +859,22 @@ int kdbus_conn_kmsg_send(struct kdbus_ep *ep,
        name_entry = kdbus_name_unlock(bus->name_registry, name_entry);
 
        if (sync) {
+               struct timespec64 ts;
+               u64 now, timeout;
+
                BUG_ON(!reply_wait);
+
+               ktime_get_ts64(&ts);
+               now = timespec64_to_ns(&ts);
+
+               if (unlikely(msg->timeout_ns <= now))
+                       timeout = 0;
+               else
+                       timeout = msg->timeout_ns - now;
+
                usecs = div_u64(msg->timeout_ns, 1000ULL);
                ret = kdbus_conn_wait_reply(ep, conn_src, conn_dst, msg,
-                                           reply_wait, usecs);
+                                           reply_wait, timeout);
        }
 
 exit_unref:
diff --git a/kdbus.h b/kdbus.h
index 087d50aabbadca7892ebf786a858f7cce52e4569..50b4ec41b318178bcc93ed02d10ff4c79620ece0 100644 (file)
--- a/kdbus.h
+++ b/kdbus.h
@@ -384,7 +384,8 @@ enum kdbus_payload_type {
  * @timeout_ns:                The time to wait for a message reply from the peer.
  *                     If there is no reply, a kernel-generated message
  *                     with an attached KDBUS_ITEM_REPLY_TIMEOUT item
- *                     is sent to @src_id.
+ *                     is sent to @src_id. The timeout is expected in
+ *                     nanoseconds and as absolute CLOCK_MONOTONIC value.
  * @cookie_reply:      A reply to the requesting message with the same
  *                     cookie. The requesting connection can match its
  *                     request and the reply with this value
index 944d2833577953cfd62cd5304522f61bcea7c020..11da3acf9f24716482866b9dc16a770a682aba15 100644 (file)
--- a/kdbus.txt
+++ b/kdbus.txt
@@ -673,7 +673,8 @@ struct kdbus_msg {
       the timeout_ns field must be set to a non-zero number of nanoseconds in
       which the receiving peer is expected to reply. If such a reply is not
       received in time, the sender will be notified with a timeout message
-      (see below).
+      (see below). The value must be an absolute value, in nanoseconds and
+      based on CLOCK_MONOTONIC.
 
       For a message to be accepted as reply, it must be a direct message to
       the original sender (not a broadcast), and its kdbus_msg.reply_cookie
@@ -737,7 +738,8 @@ struct kdbus_msg {
 
   __u64 timeout_ns;
     If the message sent requires a reply from the remote peer (see above),
-    this field contains the timeout in nanoseconds.
+    this field contains the timeout in absolute nanoseconds based on
+    CLOCK_MONOTONIC.
 
   __u64 cookie_reply;
     If the message sent is a reply to another message, this field must
index 5b9ff06514fa3f56e27da056d8d0ce8ce85ce9e3..2eef0e773e91e1e51ae991f32285eca135e4edde 100644 (file)
@@ -323,6 +323,7 @@ int kdbus_msg_send(const struct kdbus_conn *conn,
        const char ref1[1024 * 128 + 3] = "0123456789_0";
        const char ref2[] = "0123456789_1";
        struct kdbus_item *item;
+       struct timespec now;
        uint64_t size;
        int memfd = -1;
        int ret;
@@ -369,7 +370,6 @@ int kdbus_msg_send(const struct kdbus_conn *conn,
 
        memset(msg, 0, size);
        msg->flags = flags;
-       msg->timeout_ns = timeout;
        msg->priority = priority;
        msg->size = size;
        msg->src_id = conn->id;
@@ -377,6 +377,15 @@ int kdbus_msg_send(const struct kdbus_conn *conn,
        msg->cookie = cookie;
        msg->payload_type = KDBUS_PAYLOAD_DBUS;
 
+       if (timeout) {
+               ret = clock_gettime(CLOCK_MONOTONIC_COARSE, &now);
+               if (ret < 0)
+                       return ret;
+
+               msg->timeout_ns = now.tv_sec * 1000000000ULL +
+                                 now.tv_nsec + timeout;
+       }
+
        item = msg->items;
 
        if (name) {