Module: xenomai-head
Branch: master
Commit: 364fa9ad2dc66e5dd884f795ace544d1a9ae69bb
URL:    
http://git.xenomai.org/?p=xenomai-head.git;a=commit;h=364fa9ad2dc66e5dd884f795ace544d1a9ae69bb

Author: Philippe Gerum <r...@xenomai.org>
Date:   Mon Sep  7 21:56:50 2009 +0200

rtipc: use standard SOL_SOCKET level operations for timeout settings

---

 examples/rtdm/profiles/ipc/xddp-label.c |   13 +++--
 include/rtdm/rtipc.h                    |   15 ++----
 ksrc/drivers/ipc/iddp.c                 |   77 +++++++++++++++++++++++--------
 ksrc/drivers/ipc/internal.h             |   18 +++++++
 ksrc/drivers/ipc/xddp.c                 |   60 ++++++++++++++++++------
 5 files changed, 134 insertions(+), 49 deletions(-)

diff --git a/examples/rtdm/profiles/ipc/xddp-label.c 
b/examples/rtdm/profiles/ipc/xddp-label.c
index fe19365..337566c 100644
--- a/examples/rtdm/profiles/ipc/xddp-label.c
+++ b/examples/rtdm/profiles/ipc/xddp-label.c
@@ -116,7 +116,7 @@ void *realtime_thread1(void *arg)
         */
        strcpy(label, XDDP_PORT_LABEL);
        ret = setsockopt(s, SOL_RTIPC, XDDP_SETLABEL,
-                        &label, sizeof(label));
+                        label, sizeof(label));
        if (ret)
                fail("setsockopt");
        /*
@@ -155,8 +155,8 @@ void *realtime_thread2(void *arg)
        char label[XDDP_LABEL_LEN];
        struct sockaddr_ipc saddr;
        int ret, s, n = 0, len;
-       nanosecs_rel_t timeout;
        struct timespec ts;
+       struct timeval tv;
        socklen_t addrlen;
        char buf[128];
 
@@ -173,9 +173,10 @@ void *realtime_thread2(void *arg)
         * one second until a socket is bound to a port using the same
         * label, or return with a timeout error.
         */
-       timeout = 1000000000ULL; /* nanoseconds */
-       ret = setsockopt(s, SOL_RTIPC, XDDP_SETTIMEOUT,
-                        &timeout, sizeof(timeout));
+       tv.tv_sec = 1;
+       tv.tv_usec = 0;
+       ret = setsockopt(s, SOL_SOCKET, SO_RCVTIMEO,
+                        &tv, sizeof(tv));
        if (ret)
                fail("setsockopt");
 
@@ -185,7 +186,7 @@ void *realtime_thread2(void *arg)
         */
        strcpy(label, XDDP_PORT_LABEL);
        ret = setsockopt(s, SOL_RTIPC, XDDP_SETLABEL,
-                        &label, sizeof(label));
+                        label, sizeof(label));
        if (ret)
                fail("setsockopt");
 
diff --git a/include/rtdm/rtipc.h b/include/rtdm/rtipc.h
index d49c492..5be0483 100644
--- a/include/rtdm/rtipc.h
+++ b/include/rtdm/rtipc.h
@@ -79,15 +79,12 @@ enum {
 
 /* SOL_RTIPC level option names (via setsockopt) */
 #define XDDP_SETSTREAMBUF      1
-#define XDDP_SETTIMEOUT                2
-#define XDDP_SETMONITOR                3
-#define XDDP_SETLOCALPOOL      4
-#define XDDP_SETLABEL          5
-#define XDDP_GETLABEL          6
-#define IDDP_SETTXTIMEOUT      7
-#define IDDP_SETRXTIMEOUT      8
-#define IDDP_SETLOCALPOOL      9
-#define IDDP_GETSTALLCOUNT     10
+#define XDDP_SETMONITOR                2
+#define XDDP_SETLOCALPOOL      3
+#define XDDP_SETLABEL          4
+#define XDDP_GETLABEL          5
+#define IDDP_SETLOCALPOOL      6
+#define IDDP_GETSTALLCOUNT     7
 
 #define XDDP_LABEL_LEN         XNOBJECT_NAME_LEN
 
diff --git a/ksrc/drivers/ipc/iddp.c b/ksrc/drivers/ipc/iddp.c
index 7cdcae8..8e547fc 100644
--- a/ksrc/drivers/ipc/iddp.c
+++ b/ksrc/drivers/ipc/iddp.c
@@ -631,36 +631,46 @@ static int __iddp_setsockopt(struct iddp_socket *sk,
                             void *arg)
 {
        struct _rtdm_setsockopt_args sopt;
-       nanosecs_rel_t timeout;
+       struct timeval tv;
        int ret = 0;
        size_t len;
 
        if (rtipc_get_arg(user_info, &sopt, arg, sizeof(sopt)))
                return -EFAULT;
 
+       if (sopt.level == SOL_SOCKET) {
+               switch (sopt.optname) {
+
+               case SO_RCVTIMEO:
+                       if (sopt.optlen != sizeof(tv))
+                               return -EINVAL;
+                       if (rtipc_get_arg(user_info, &tv,
+                                         sopt.optval, sizeof(tv)))
+                               return -EFAULT;
+                       sk->rx_timeout = rtipc_timeval_to_ns(&tv);
+                       break;
+
+               case SO_SNDTIMEO:
+                       if (sopt.optlen != sizeof(tv))
+                               return -EINVAL;
+                       if (rtipc_get_arg(user_info, &tv,
+                                         sopt.optval, sizeof(tv)))
+                               return -EFAULT;
+                       sk->tx_timeout = rtipc_timeval_to_ns(&tv);
+                       break;
+
+               default:
+                       ret = -EINVAL;
+               }
+
+               return ret;
+       }
+
        if (sopt.level != SOL_RTIPC)
                return -ENOPROTOOPT;
 
        switch (sopt.optname) {
 
-       case IDDP_SETRXTIMEOUT:
-               if (sopt.optlen != sizeof(timeout))
-                       return -EINVAL;
-               if (rtipc_get_arg(user_info, &timeout,
-                                 sopt.optval, sizeof(timeout)))
-                       return -EFAULT;
-               sk->rx_timeout = timeout;
-               break;
-
-       case IDDP_SETTXTIMEOUT:
-               if (sopt.optlen != sizeof(timeout))
-                       return -EINVAL;
-               if (rtipc_get_arg(user_info, &timeout,
-                                 sopt.optval, sizeof(timeout)))
-                       return -EFAULT;
-               sk->tx_timeout = timeout;
-               break;
-
        case IDDP_SETLOCALPOOL:
                if (sopt.optlen != sizeof(len))
                        return -EINVAL;
@@ -700,6 +710,7 @@ static int __iddp_getsockopt(struct iddp_socket *sk,
                             void *arg)
 {
        struct _rtdm_getsockopt_args sopt;
+       struct timeval tv;
        socklen_t len;
        int ret = 0;
 
@@ -709,6 +720,34 @@ static int __iddp_getsockopt(struct iddp_socket *sk,
        if (rtipc_get_arg(user_info, &len, sopt.optlen, sizeof(len)))
                return -EFAULT;
 
+       if (sopt.level == SOL_SOCKET) {
+               switch (sopt.optname) {
+
+               case SO_RCVTIMEO:
+                       if (len != sizeof(tv))
+                               return -EINVAL;
+                       rtipc_ns_to_timeval(&tv, sk->rx_timeout);
+                       if (rtipc_put_arg(user_info, sopt.optval,
+                                         &tv, sizeof(tv)))
+                               return -EFAULT;
+                       break;
+
+               case SO_SNDTIMEO:
+                       if (len != sizeof(tv))
+                               return -EINVAL;
+                       rtipc_ns_to_timeval(&tv, sk->tx_timeout);
+                       if (rtipc_put_arg(user_info, sopt.optval,
+                                         &tv, sizeof(tv)))
+                               return -EFAULT;
+                       break;
+
+               default:
+                       ret = -EINVAL;
+               }
+
+               return ret;
+       }
+
        if (sopt.level != SOL_RTIPC)
                return -ENOPROTOOPT;
 
diff --git a/ksrc/drivers/ipc/internal.h b/ksrc/drivers/ipc/internal.h
index 5099ff5..732501c 100644
--- a/ksrc/drivers/ipc/internal.h
+++ b/ksrc/drivers/ipc/internal.h
@@ -59,6 +59,24 @@ struct rtipc_protocol {
        } proto_ops;
 };
 
+static inline nanosecs_rel_t rtipc_timeval_to_ns(const struct timeval *tv)
+{
+       nanosecs_rel_t ns = tv->tv_usec * 1000;
+
+       if (tv->tv_sec)
+               ns += (nanosecs_rel_t)tv->tv_sec * 1000000000UL;
+
+       return ns;
+}
+
+static inline void rtipc_ns_to_timeval(struct timeval *tv, nanosecs_rel_t ns)
+{
+       unsigned long nsecs;
+       
+       tv->tv_sec = xnarch_divrem_billion(ns, &nsecs);
+       tv->tv_usec = nsecs / 1000;
+}
+
 extern struct rtipc_protocol xddp_proto_driver;
 
 extern struct rtipc_protocol iddp_proto_driver;
diff --git a/ksrc/drivers/ipc/xddp.c b/ksrc/drivers/ipc/xddp.c
index 8e5f8e0..bb54adc 100644
--- a/ksrc/drivers/ipc/xddp.c
+++ b/ksrc/drivers/ipc/xddp.c
@@ -795,11 +795,11 @@ static int __xddp_connect_socket(struct xddp_socket *sk,
         * immediately, regardless of whether the destination is
         * bound at the time of the call.
         *
-        * - If sipc_port is -1 and a label exists, connect() blocks
-        * for the requested amount of time until a socket is bound to
-        * the same label, unless the internal timeout (see
-        * XDDP_SETTIMEOUT) specifies a non-blocking operation
-        * (RTDM_TIMEOUT_NONE).
+        * - If sipc_port is -1 and a label was set via XDDP_SETLABEL,
+        * connect() blocks for the requested amount of time until a
+        * socket is bound to the same label, unless the internal
+        * timeout (see SO_RCVTIMEO) specifies a non-blocking
+        * operation (RTDM_TIMEOUT_NONE).
         *
         * - If sipc_port is -1 and no label is given, the default
         * destination address is cleared, meaning that any subsequent
@@ -900,13 +900,32 @@ static int __xddp_setsockopt(struct xddp_socket *sk,
        struct _rtdm_setsockopt_args sopt;
        char label[XDDP_LABEL_LEN];
        rtdm_lockctx_t lockctx;
-       nanosecs_rel_t timeout;
+       struct timeval tv;
        int ret = 0;
        size_t len;
 
        if (rtipc_get_arg(user_info, &sopt, arg, sizeof(sopt)))
                return -EFAULT;
 
+       if (sopt.level == SOL_SOCKET) {
+               switch (sopt.optname) {
+
+               case SO_RCVTIMEO:
+                       if (sopt.optlen != sizeof(tv))
+                               return -EINVAL;
+                       if (rtipc_get_arg(user_info, &tv,
+                                         sopt.optval, sizeof(tv)))
+                               return -EFAULT;
+                       sk->timeout = rtipc_timeval_to_ns(&tv);
+                       break;
+
+               default:
+                       ret = -EINVAL;
+               }
+
+               return ret;
+       }
+
        if (sopt.level != SOL_RTIPC)
                return -ENOPROTOOPT;
 
@@ -951,15 +970,6 @@ static int __xddp_setsockopt(struct xddp_socket *sk,
                );
                break;
 
-       case XDDP_SETTIMEOUT:
-               if (sopt.optlen != sizeof(timeout))
-                       return -EINVAL;
-               if (rtipc_get_arg(user_info, &timeout,
-                                 sopt.optval, sizeof(timeout)))
-                       return -EFAULT;
-               sk->timeout = timeout;
-               break;
-
        case XDDP_SETMONITOR:
                /* Monitoring is available from kernel-space only. */
                if (user_info)
@@ -1002,6 +1012,7 @@ static int __xddp_getsockopt(struct xddp_socket *sk,
 {
        struct _rtdm_getsockopt_args sopt;
        char label[XDDP_LABEL_LEN];
+       struct timeval tv;
        socklen_t len;
        int ret = 0;
 
@@ -1011,6 +1022,25 @@ static int __xddp_getsockopt(struct xddp_socket *sk,
        if (rtipc_get_arg(user_info, &len, sopt.optlen, sizeof(len)))
                return -EFAULT;
 
+       if (sopt.level == SOL_SOCKET) {
+               switch (sopt.optname) {
+
+               case SO_RCVTIMEO:
+                       if (len != sizeof(tv))
+                               return -EINVAL;
+                       rtipc_ns_to_timeval(&tv, sk->timeout);
+                       if (rtipc_put_arg(user_info, sopt.optval,
+                                         &tv, sizeof(tv)))
+                               return -EFAULT;
+                       break;
+
+               default:
+                       ret = -EINVAL;
+               }
+
+               return ret;
+       }
+
        if (sopt.level != SOL_RTIPC)
                return -ENOPROTOOPT;
 


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to