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