From 5c5c08efcd018a7fa1d08cf739ab12f7b0829b78 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Sat, 4 Jan 2020 18:37:46 +0800 Subject: [PATCH] network: simplify the timeout process logic 1.Consolidate absolute to relative timeout conversion into one place(_net_timedwait) 2.Drive the wait timeout logic by net_timedwait instead of devif_timer This patch help us remove devif_timer(period tick) to save the power in the future. Change-Id: I534748a5d767ca6da8a7843c3c2f993ed9ea77d4 Signed-off-by: Xiang Xiao --- include/nuttx/net/neighbor.h | 1 + include/nuttx/net/net.h | 10 +- net/arp/arp.h | 3 +- net/arp/arp_notify.c | 28 +----- net/arp/arp_send.c | 21 +--- net/bluetooth/bluetooth_recvfrom.c | 1 - net/bluetooth/bluetooth_sendto.c | 1 - net/devif/devif.h | 1 - net/icmp/icmp_recvfrom.c | 67 ++----------- net/icmp/icmp_sendto.c | 106 +++++--------------- net/icmpv6/icmpv6.h | 7 +- net/icmpv6/icmpv6_autoconfig.c | 21 +--- net/icmpv6/icmpv6_neighbor.c | 21 +--- net/icmpv6/icmpv6_notify.c | 32 +----- net/icmpv6/icmpv6_recvfrom.c | 67 ++----------- net/icmpv6/icmpv6_rnotify.c | 32 +----- net/icmpv6/icmpv6_sendto.c | 108 +++++---------------- net/ieee802154/ieee802154_recvfrom.c | 1 - net/ieee802154/ieee802154_sendto.c | 1 - net/inet/inet.h | 6 +- net/inet/inet_close.c | 62 +++--------- net/inet/inet_recvfrom.c | 134 ++------------------------ net/inet/inet_txdrain.c | 9 +- net/neighbor/neighbor.h | 1 - net/neighbor/neighbor_globals.c | 1 - net/pkt/pkt_recvfrom.c | 1 - net/pkt/pkt_send.c | 1 - net/sixlowpan/sixlowpan_internal.h | 2 +- net/sixlowpan/sixlowpan_reassbuf.c | 3 +- net/sixlowpan/sixlowpan_send.c | 68 ++----------- net/sixlowpan/sixlowpan_tcpsend.c | 91 +++-------------- net/sixlowpan/sixlowpan_udpsend.c | 9 +- net/socket/socket.h | 8 ++ net/tcp/tcp.h | 9 +- net/tcp/tcp_conn.c | 1 - net/tcp/tcp_getsockopt.c | 1 - net/tcp/tcp_input.c | 1 - net/tcp/tcp_send_buffered.c | 1 - net/tcp/tcp_send_unbuffered.c | 87 +++-------------- net/tcp/tcp_sendfile.c | 100 ++++--------------- net/tcp/tcp_setsockopt.c | 2 - net/tcp/tcp_txdrain.c | 8 +- net/tcp/tcp_wrbuffer.c | 2 +- net/udp/udp.h | 13 +-- net/udp/udp_psock_sendto_buffered.c | 68 ------------- net/udp/udp_psock_sendto_unbuffered.c | 87 +++-------------- net/udp/udp_setsockopt.c | 2 - net/udp/udp_txdrain.c | 8 +- net/udp/udp_wrbuffer.c | 2 +- net/usrsock/usrsock_accept.c | 26 +---- net/usrsock/usrsock_dev.c | 13 +-- net/usrsock/usrsock_recvfrom.c | 26 +---- net/usrsock/usrsock_sendto.c | 26 +---- net/utils/net_lock.c | 41 +++++--- 54 files changed, 242 insertions(+), 1207 deletions(-) diff --git a/include/nuttx/net/neighbor.h b/include/nuttx/net/neighbor.h index 0d0382110b..57bb527eac 100644 --- a/include/nuttx/net/neighbor.h +++ b/include/nuttx/net/neighbor.h @@ -50,6 +50,7 @@ #include #include +#include #include #include diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h index 1efa774e62..5924ecbf45 100644 --- a/include/nuttx/net/net.h +++ b/include/nuttx/net/net.h @@ -370,7 +370,7 @@ void net_unlock(void); * * Input Parameters: * sem - A reference to the semaphore to be taken. - * abstime - The absolute time to wait until a timeout is declared. + * timeout - The relative time to wait until a timeout is declared. * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned on @@ -378,8 +378,7 @@ void net_unlock(void); * ****************************************************************************/ -struct timespec; -int net_timedwait(sem_t *sem, FAR const struct timespec *abstime); +int net_timedwait(sem_t *sem, unsigned int timeout); /**************************************************************************** * Name: net_lockedwait @@ -412,7 +411,7 @@ int net_lockedwait(sem_t *sem); * * Input Parameters: * sem - A reference to the semaphore to be taken. - * abstime - The absolute time to wait until a timeout is declared. + * timeout - The relative time to wait until a timeout is declared. * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned on @@ -420,8 +419,7 @@ int net_lockedwait(sem_t *sem); * ****************************************************************************/ -int net_timedwait_uninterruptible(sem_t *sem, - FAR const struct timespec *abstime); +int net_timedwait_uninterruptible(sem_t *sem, unsigned int timeout); /**************************************************************************** * Name: net_lockedwait_uninterruptible diff --git a/net/arp/arp.h b/net/arp/arp.h index b1eaad4e19..3214b36b0e 100644 --- a/net/arp/arp.h +++ b/net/arp/arp.h @@ -292,8 +292,7 @@ int arp_wait_cancel(FAR struct arp_notify_s *notify); ****************************************************************************/ #ifdef CONFIG_NET_ARP_SEND -struct timespec; -int arp_wait(FAR struct arp_notify_s *notify, FAR struct timespec *timeout); +int arp_wait(FAR struct arp_notify_s *notify, unsigned int timeout); #else # define arp_wait(n,t) (0) #endif diff --git a/net/arp/arp_notify.c b/net/arp/arp_notify.c index 628ced4d2c..4176b9c6f9 100644 --- a/net/arp/arp_notify.c +++ b/net/arp/arp_notify.c @@ -39,7 +39,6 @@ #include -#include #include #include #include @@ -168,30 +167,13 @@ int arp_wait_cancel(FAR struct arp_notify_s *notify) * ****************************************************************************/ -int arp_wait(FAR struct arp_notify_s *notify, FAR struct timespec *timeout) +int arp_wait(FAR struct arp_notify_s *notify, unsigned int timeout) { - struct timespec abstime; - irqstate_t flags; int ret; - /* And wait for the ARP response (or a timeout). Interrupts will be re- - * enabled while we wait. - */ + /* And wait for the ARP response (or a timeout). */ - flags = enter_critical_section(); - DEBUGVERIFY(clock_gettime(CLOCK_REALTIME, &abstime)); - - abstime.tv_sec += timeout->tv_sec; - abstime.tv_nsec += timeout->tv_nsec; - if (abstime.tv_nsec >= 1000000000) - { - abstime.tv_sec++; - abstime.tv_nsec -= 1000000000; - } - - /* Wait to get either the correct response or a timeout. */ - - net_timedwait_uninterruptible(¬ify->nt_sem, &abstime); + net_timedwait_uninterruptible(¬ify->nt_sem, timeout); /* Then get the real result of the transfer */ @@ -202,10 +184,6 @@ int arp_wait(FAR struct arp_notify_s *notify, FAR struct timespec *timeout) */ arp_wait_cancel(notify); - - /* Re-enable interrupts and return the result of the wait */ - - leave_critical_section(flags); return ret; } diff --git a/net/arp/arp_send.c b/net/arp/arp_send.c index f19d28b551..f3696efde1 100644 --- a/net/arp/arp_send.c +++ b/net/arp/arp_send.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include @@ -61,15 +60,6 @@ #ifdef CONFIG_NET_ARP_SEND -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define CONFIG_ARP_SEND_DELAYSEC \ - (CONFIG_ARP_SEND_DELAYMSEC / 1000) -#define CONFIG_ARP_SEND_DELAYNSEC \ - ((CONFIG_ARP_SEND_DELAYMSEC - 1000*CONFIG_ARP_SEND_DELAYSEC) * 1000000) - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -202,7 +192,6 @@ int arp_send(in_addr_t ipaddr) { FAR struct net_driver_s *dev; struct arp_notify_s notify; - struct timespec delay; struct arp_send_s state; int ret; @@ -324,11 +313,6 @@ int arp_send(in_addr_t ipaddr) * sending the ARP request if it is not. */ - /* The optimal delay would be the worst case round trip time. */ - - delay.tv_sec = CONFIG_ARP_SEND_DELAYSEC; - delay.tv_nsec = CONFIG_ARP_SEND_DELAYNSEC; - ret = -ETIMEDOUT; /* Assume a timeout failure */ while (state.snd_retries < CONFIG_ARP_SEND_MAXTRIES) @@ -387,7 +371,7 @@ int arp_send(in_addr_t ipaddr) /* Now wait for response to the ARP response to be received. */ - ret = arp_wait(¬ify, &delay); + ret = arp_wait(¬ify, CONFIG_ARP_SEND_DELAYMSEC); /* arp_wait will return OK if and only if the matching ARP response * is received. Otherwise, it will return -ETIMEDOUT. @@ -400,10 +384,9 @@ int arp_send(in_addr_t ipaddr) break; } - /* Increment the retry count and double the delay time */ + /* Increment the retry count */ state.snd_retries++; - clock_timespec_add(&delay, &delay, &delay); nerr("ERROR: arp_wait failed: %d\n", ret); } diff --git a/net/bluetooth/bluetooth_recvfrom.c b/net/bluetooth/bluetooth_recvfrom.c index 60964680fe..bacd04b884 100644 --- a/net/bluetooth/bluetooth_recvfrom.c +++ b/net/bluetooth/bluetooth_recvfrom.c @@ -50,7 +50,6 @@ #include #include -#include #include #include #include diff --git a/net/bluetooth/bluetooth_sendto.c b/net/bluetooth/bluetooth_sendto.c index 931e26809c..6f939e268c 100644 --- a/net/bluetooth/bluetooth_sendto.c +++ b/net/bluetooth/bluetooth_sendto.c @@ -52,7 +52,6 @@ #include #include -#include #include #include #include diff --git a/net/devif/devif.h b/net/devif/devif.h index f3aef4e4dc..cbe1a005cb 100644 --- a/net/devif/devif.h +++ b/net/devif/devif.h @@ -51,7 +51,6 @@ #include #include -#include #include /**************************************************************************** diff --git a/net/icmp/icmp_recvfrom.c b/net/icmp/icmp_recvfrom.c index 8ef86d1230..1a8fc0718d 100644 --- a/net/icmp/icmp_recvfrom.c +++ b/net/icmp/icmp_recvfrom.c @@ -71,7 +71,6 @@ struct icmp_recvfrom_s FAR struct devif_callback_s *recv_cb; /* Reference to callback instance */ FAR struct socket *recv_sock; /* IPPROTO_ICMP socket structure */ sem_t recv_sem; /* Use to manage the wait for the response */ - clock_t recv_time; /* Start time for determining timeouts */ in_addr_t recv_from; /* The peer we received the request from */ FAR uint8_t *recv_buf; /* Location to return the response */ uint16_t recv_buflen; /* Size of the response */ @@ -83,46 +82,6 @@ struct icmp_recvfrom_s * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: recvfrom_timeout - * - * Description: - * Check for send timeout. - * - * Input Parameters: - * pstate - Reference to instance ot recvfrom state structure - * - * Returned Value: - * true: timeout false: no timeout - * - * Assumptions: - * The network is locked - * - ****************************************************************************/ - -#ifdef CONFIG_NET_SOCKOPTS -static inline int recvfrom_timeout(FAR struct icmp_recvfrom_s *pstate) -{ - FAR struct socket *psock; - - /* Check for a timeout configured via setsockopts(SO_SNDTIMEO). - * If none... we will let the send wait forever. - */ - - psock = pstate->recv_sock; - if (psock != NULL && psock->s_rcvtimeo != 0) - { - /* Check if the configured timeout has elapsed */ - - return net_timeo(pstate->recv_time, psock->s_rcvtimeo); - } - - /* No timeout */ - - return false; -} -#endif /* CONFIG_NET_SOCKOPTS */ - /**************************************************************************** * Name: recvfrom_eventhandler * @@ -239,17 +198,6 @@ static uint16_t recvfrom_eventhandler(FAR struct net_driver_s *dev, goto end_wait; } -#ifdef CONFIG_NET_SOCKOPTS - /* Check if the selected timeout has elapsed */ - - if (recvfrom_timeout(pstate)) - { - nerr("ERROR: recvfrom() timeout\n"); - pstate->recv_result = -ETIMEDOUT; - goto end_wait; - } -#endif - /* Continue waiting */ } @@ -477,9 +425,6 @@ ssize_t icmp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, state.recv_buf = buf; /* Location to return the response */ state.recv_buflen = len; /* Size of the response */ - net_lock(); - state.recv_time = clock_systimer(); - /* Get the device that was used to send the ICMP request. */ dev = conn->dev; @@ -490,6 +435,8 @@ ssize_t icmp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, goto errout; } + net_lock(); + /* Set up the callback */ state.recv_cb = icmp_callback_alloc(dev, conn); @@ -498,14 +445,16 @@ ssize_t icmp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, state.recv_cb->flags = (ICMP_NEWDATA | NETDEV_DOWN); state.recv_cb->priv = (FAR void *)&state; state.recv_cb->event = recvfrom_eventhandler; - state.recv_result = -EINTR; /* Assume sem-wait interrupted by signal */ /* Wait for either the response to be received or for timeout to - * occur. net_lockedwait will also terminate if a signal is received. + * occur. net_timedwait will also terminate if a signal is received. */ - ninfo("Start time: 0x%08x\n", state.recv_time); - net_lockedwait(&state.recv_sem); + ret = net_timedwait(&state.recv_sem, _SO_TIMEOUT(psock->s_rcvtimeo)); + if (ret < 0) + { + state.recv_result = ret; + } icmp_callback_free(dev, conn, state.recv_cb); } diff --git a/net/icmp/icmp_sendto.c b/net/icmp/icmp_sendto.c index c50acf2ca1..b88fcaf14c 100644 --- a/net/icmp/icmp_sendto.c +++ b/net/icmp/icmp_sendto.c @@ -87,9 +87,7 @@ struct icmp_sendto_s { FAR struct devif_callback_s *snd_cb; /* Reference to callback instance */ - FAR struct socket *snd_sock; /* IPPROTO_ICMP socket structure */ sem_t snd_sem; /* Use to manage the wait for send complete */ - clock_t snd_time; /* Start time for determining timeouts */ in_addr_t snd_toaddr; /* The peer to send the request to */ FAR const uint8_t *snd_buf; /* ICMP header + data payload */ uint16_t snd_buflen; /* Size of the ICMP header + data payload */ @@ -100,46 +98,6 @@ struct icmp_sendto_s * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: sendto_timeout - * - * Description: - * Check for send timeout. - * - * Input Parameters: - * pstate - Reference to instance ot sendto state structure - * - * Returned Value: - * true: timeout false: no timeout - * - * Assumptions: - * The network is locked - * - ****************************************************************************/ - -#ifdef CONFIG_NET_SOCKOPTS -static inline int sendto_timeout(FAR struct icmp_sendto_s *pstate) -{ - FAR struct socket *psock; - - /* Check for a timeout configured via setsockopts(SO_SNDTIMEO). - * If none... we will let the send wait forever. - */ - - psock = pstate->snd_sock; - if (psock != NULL && psock->s_sndtimeo != 0) - { - /* Check if the configured timeout has elapsed */ - - return net_timeo(pstate->snd_time, psock->s_sndtimeo); - } - - /* No timeout */ - - return false; -} -#endif /* CONFIG_NET_SOCKOPTS */ - /**************************************************************************** * Name: sendto_request * @@ -289,41 +247,6 @@ static uint16_t sendto_eventhandler(FAR struct net_driver_s *dev, goto end_wait; } -#ifdef CONFIG_NET_SOCKOPTS - /* Check if the selected timeout has elapsed */ - - if (sendto_timeout(pstate)) - { - int failcode; - - /* Check if this device is on the same network as the destination - * device. - */ - - if (!net_ipv4addr_maskcmp(pstate->snd_toaddr, dev->d_ipaddr, - dev->d_netmask)) - { - /* Destination address was not on the local network served by - * this device. If a timeout occurs, then the most likely - * reason is that the destination address is not reachable. - */ - - nerr("ERROR: Not reachable\n"); - failcode = -ENETUNREACH; - } - else - { - nerr("ERROR: sendto() timeout\n"); - failcode = -ETIMEDOUT; - } - - /* Report the failure */ - - pstate->snd_result = failcode; - goto end_wait; - } -#endif - /* Continue waiting */ } @@ -445,14 +368,12 @@ ssize_t icmp_sendto(FAR struct socket *psock, FAR const void *buf, size_t len, nxsem_init(&state.snd_sem, 0, 0); nxsem_setprotocol(&state.snd_sem, SEM_PRIO_NONE); - state.snd_sock = psock; /* The IPPROTO_ICMP socket instance */ state.snd_result = -ENOMEM; /* Assume allocation failure */ state.snd_toaddr = inaddr->sin_addr.s_addr; /* Address of the peer to send the request */ state.snd_buf = buf; /* ICMP header + data payload */ state.snd_buflen = len; /* Size of the ICMP header + data payload */ net_lock(); - state.snd_time = clock_systimer(); /* Set up the callback */ @@ -462,7 +383,6 @@ ssize_t icmp_sendto(FAR struct socket *psock, FAR const void *buf, size_t len, state.snd_cb->flags = (ICMP_POLL | NETDEV_DOWN); state.snd_cb->priv = (FAR void *)&state; state.snd_cb->event = sendto_eventhandler; - state.snd_result = -EINTR; /* Assume sem-wait interrupted by signal */ /* Setup to receive ICMP ECHO replies */ @@ -479,11 +399,31 @@ ssize_t icmp_sendto(FAR struct socket *psock, FAR const void *buf, size_t len, netdev_txnotify_dev(dev); /* Wait for either the send to complete or for timeout to occur. - * net_lockedwait will also terminate if a signal is received. + * net_timedwait will also terminate if a signal is received. */ - ninfo("Start time: 0x%08x\n", state.snd_time); - net_lockedwait(&state.snd_sem); + ret = net_timedwait(&state.snd_sem, _SO_TIMEOUT(psock->s_sndtimeo)); + if (ret < 0) + { + if (ret == -ETIMEDOUT) + { + /* Check if this device is on the same network as the destination + * device. + */ + + if (!net_ipv4addr_maskcmp(state.snd_toaddr, dev->d_ipaddr, + dev->d_netmask)) + { + /* Destination address was not on the local network served by + * this device. If a timeout occurs, then the most likely + * reason is that the destination address is not reachable. + */ + + ret = -ENETUNREACH; + } + } + state.snd_result = ret; + } icmp_callback_free(dev, conn, state.snd_cb); } diff --git a/net/icmpv6/icmpv6.h b/net/icmpv6/icmpv6.h index f5f2ab5fce..f9db0e0432 100644 --- a/net/icmpv6/icmpv6.h +++ b/net/icmpv6/icmpv6.h @@ -71,7 +71,6 @@ * Public Type Definitions ****************************************************************************/ -struct timespec; /* Forward reference */ struct net_driver_s; /* Forward reference */ struct socket; /* Forward reference */ struct sockaddr; /* Forward reference */ @@ -399,8 +398,7 @@ int icmpv6_wait_cancel(FAR struct icmpv6_notify_s *notify); ****************************************************************************/ #ifdef CONFIG_NET_ICMPv6_NEIGHBOR -int icmpv6_wait(FAR struct icmpv6_notify_s *notify, - FAR struct timespec *timeout); +int icmpv6_wait(FAR struct icmpv6_notify_s *notify, unsigned int timeout); #else # define icmpv6_wait(n,t) (0) #endif @@ -503,8 +501,7 @@ int icmpv6_rwait_cancel(FAR struct icmpv6_rnotify_s *notify); ****************************************************************************/ #ifdef CONFIG_NET_ICMPv6_AUTOCONF -int icmpv6_rwait(FAR struct icmpv6_rnotify_s *notify, - FAR struct timespec *timeout); +int icmpv6_rwait(FAR struct icmpv6_rnotify_s *notify, unsigned int timeout); #else # define icmpv6_rwait(n,t) (0) #endif diff --git a/net/icmpv6/icmpv6_autoconfig.c b/net/icmpv6/icmpv6_autoconfig.c index 6edd23fbee..68271a4cb4 100644 --- a/net/icmpv6/icmpv6_autoconfig.c +++ b/net/icmpv6/icmpv6_autoconfig.c @@ -41,7 +41,6 @@ #include #include -#include #include #include @@ -58,15 +57,6 @@ #ifdef CONFIG_NET_ICMPv6_AUTOCONF -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define CONFIG_ICMPv6_AUTOCONF_DELAYSEC \ - (CONFIG_ICMPv6_AUTOCONF_DELAYMSEC / 1000) -#define CONFIG_ICMPv6_AUTOCONF_DELAYNSEC \ - ((CONFIG_ICMPv6_AUTOCONF_DELAYMSEC - 1000*CONFIG_ICMPv6_AUTOCONF_DELAYSEC) * 1000000) - /**************************************************************************** * Private Types ****************************************************************************/ @@ -293,7 +283,6 @@ errout_with_semaphore: int icmpv6_autoconfig(FAR struct net_driver_s *dev) { struct icmpv6_rnotify_s notify; - struct timespec delay; net_ipv6addr_t lladdr; int retries; int ret; @@ -374,11 +363,6 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev) net_ipv6addr_copy(dev->d_ipv6addr, lladdr); - /* The optimal delay would be the worst case round trip time. */ - - delay.tv_sec = CONFIG_ICMPv6_AUTOCONF_DELAYSEC; - delay.tv_nsec = CONFIG_ICMPv6_AUTOCONF_DELAYNSEC; - /* 4. Router Contact: The node next attempts to contact a local router for * more information on continuing the configuration. This is done either * by listening for Router Advertisement messages sent periodically by @@ -405,7 +389,7 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev) /* Wait to receive the Router Advertisement message */ - ret = icmpv6_rwait(¬ify, &delay); + ret = icmpv6_rwait(¬ify, CONFIG_ICMPv6_AUTOCONF_DELAYMSEC); if (ret != -ETIMEDOUT) { /* ETIMEDOUT is the only expected failure. We will retry on that @@ -415,9 +399,6 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev) break; } - /* Double the delay time for the next loop */ - - clock_timespec_add(&delay, &delay, &delay); ninfo("Timed out... retrying %d\n", retries + 1); } diff --git a/net/icmpv6/icmpv6_neighbor.c b/net/icmpv6/icmpv6_neighbor.c index 8de2dbc575..359fa1d8cc 100644 --- a/net/icmpv6/icmpv6_neighbor.c +++ b/net/icmpv6/icmpv6_neighbor.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include @@ -63,15 +62,6 @@ #ifdef CONFIG_NET_ICMPv6_NEIGHBOR -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define CONFIG_ICMPv6_NEIGHBOR_DELAYSEC \ - (CONFIG_ICMPv6_NEIGHBOR_DELAYMSEC / 1000) -#define CONFIG_ICMPv6_NEIGHBOR_DELAYNSEC \ - ((CONFIG_ICMPv6_NEIGHBOR_DELAYMSEC - 1000*CONFIG_ICMPv6_NEIGHBOR_DELAYSEC) * 1000000) - /**************************************************************************** * Private Types ****************************************************************************/ @@ -199,7 +189,6 @@ int icmpv6_neighbor(const net_ipv6addr_t ipaddr) { FAR struct net_driver_s *dev; struct icmpv6_notify_s notify; - struct timespec delay; struct icmpv6_neighbor_s state; net_ipv6addr_t lookup; int ret; @@ -295,11 +284,6 @@ int icmpv6_neighbor(const net_ipv6addr_t ipaddr) * re-sending the Neighbor Solicitation if it is not. */ - /* The optimal delay would be the worst case round trip time. */ - - delay.tv_sec = CONFIG_ICMPv6_NEIGHBOR_DELAYSEC; - delay.tv_nsec = CONFIG_ICMPv6_NEIGHBOR_DELAYNSEC; - ret = -ETIMEDOUT; /* Assume a timeout failure */ while (state.snd_retries < CONFIG_ICMPv6_NEIGHBOR_MAXTRIES) @@ -348,7 +332,7 @@ int icmpv6_neighbor(const net_ipv6addr_t ipaddr) /* Now wait for response to the Neighbor Advertisement to be received. */ - ret = icmpv6_wait(¬ify, &delay); + ret = icmpv6_wait(¬ify, CONFIG_ICMPv6_NEIGHBOR_DELAYMSEC); /* icmpv6_wait will return OK if and only if the matching Neighbor * Advertisement is received. Otherwise, it will return -ETIMEDOUT. @@ -359,9 +343,8 @@ int icmpv6_neighbor(const net_ipv6addr_t ipaddr) break; } - /* Increment the retry count and double the delay time */ + /* Increment the retry count */ - clock_timespec_add(&delay, &delay, &delay); state.snd_retries++; } diff --git a/net/icmpv6/icmpv6_notify.c b/net/icmpv6/icmpv6_notify.c index 5c514f89ea..f883a35906 100644 --- a/net/icmpv6/icmpv6_notify.c +++ b/net/icmpv6/icmpv6_notify.c @@ -40,7 +40,6 @@ #include #include -#include #include #include #include @@ -182,44 +181,23 @@ int icmpv6_wait_cancel(FAR struct icmpv6_notify_s *notify) * ****************************************************************************/ -int icmpv6_wait(FAR struct icmpv6_notify_s *notify, - FAR struct timespec *timeout) +int icmpv6_wait(FAR struct icmpv6_notify_s *notify, unsigned int timeout) { - struct timespec abstime; - irqstate_t flags; int ret; - /* And wait for the Neighbor Advertisement (or a timeout). Interrupts will - * be re-enabled while we wait. - */ + /* And wait for the Neighbor Advertisement (or a timeout). */ - flags = enter_critical_section(); - DEBUGVERIFY(clock_gettime(CLOCK_REALTIME, &abstime)); - - abstime.tv_sec += timeout->tv_sec; - abstime.tv_nsec += timeout->tv_nsec; - if (abstime.tv_nsec >= 1000000000) + ret = net_timedwait(¬ify->nt_sem, timeout); + if (ret >= 0) { - abstime.tv_sec++; - abstime.tv_nsec -= 1000000000; + ret = notify->nt_result; } - /* REVISIT: If net_timedwait() is awakened with signal, we will return - * the wrong error code. - */ - - net_timedwait(¬ify->nt_sem, &abstime); - ret = notify->nt_result; - /* Remove our wait structure from the list (we may no longer be at the * head of the list). */ icmpv6_wait_cancel(notify); - - /* Re-enable interrupts and return the result of the wait */ - - leave_critical_section(flags); return ret; } diff --git a/net/icmpv6/icmpv6_recvfrom.c b/net/icmpv6/icmpv6_recvfrom.c index db2d435948..ce54aadbe6 100644 --- a/net/icmpv6/icmpv6_recvfrom.c +++ b/net/icmpv6/icmpv6_recvfrom.c @@ -74,7 +74,6 @@ struct icmpv6_recvfrom_s FAR struct devif_callback_s *recv_cb; /* Reference to callback instance */ FAR struct socket *recv_sock; /* IPPROTO_ICMP6 socket structure */ sem_t recv_sem; /* Use to manage the wait for the response */ - clock_t recv_time; /* Start time for determining timeouts */ struct in6_addr recv_from; /* The peer we received the request from */ FAR uint8_t *recv_buf; /* Location to return the response */ uint16_t recv_buflen; /* Size of the response */ @@ -86,46 +85,6 @@ struct icmpv6_recvfrom_s * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: recvfrom_timeout - * - * Description: - * Check for send timeout. - * - * Input Parameters: - * pstate - Reference to instance ot recvfrom state structure - * - * Returned Value: - * true: timeout false: no timeout - * - * Assumptions: - * The network is locked - * - ****************************************************************************/ - -#ifdef CONFIG_NET_SOCKOPTS -static inline int recvfrom_timeout(FAR struct icmpv6_recvfrom_s *pstate) -{ - FAR struct socket *psock; - - /* Check for a timeout configured via setsockopts(SO_SNDTIMEO). - * If none... we will let the send wait forever. - */ - - psock = pstate->recv_sock; - if (psock != NULL && psock->s_rcvtimeo != 0) - { - /* Check if the configured timeout has elapsed */ - - return net_timeo(pstate->recv_time, psock->s_rcvtimeo); - } - - /* No timeout */ - - return false; -} -#endif /* CONFIG_NET_SOCKOPTS */ - /**************************************************************************** * Name: recvfrom_eventhandler * @@ -246,17 +205,6 @@ static uint16_t recvfrom_eventhandler(FAR struct net_driver_s *dev, goto end_wait; } -#ifdef CONFIG_NET_SOCKOPTS - /* Check if the selected timeout has elapsed */ - - if (recvfrom_timeout(pstate)) - { - nerr("ERROR: recvfrom() timeout\n"); - pstate->recv_result = -ETIMEDOUT; - goto end_wait; - } -#endif - /* Continue waiting */ } @@ -484,9 +432,6 @@ ssize_t icmpv6_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, state.recv_buf = buf; /* Location to return the response */ state.recv_buflen = len; /* Size of the response */ - net_lock(); - state.recv_time = clock_systimer(); - /* Get the device that was used to send the ICMPv6 request. */ dev = conn->dev; @@ -497,6 +442,8 @@ ssize_t icmpv6_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, goto errout; } + net_lock(); + /* Set up the callback */ state.recv_cb = icmpv6_callback_alloc(dev, conn); @@ -505,17 +452,19 @@ ssize_t icmpv6_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, state.recv_cb->flags = (ICMPv6_NEWDATA | NETDEV_DOWN); state.recv_cb->priv = (FAR void *)&state; state.recv_cb->event = recvfrom_eventhandler; - state.recv_result = -EINTR; /* Assume sem-wait interrupted by signal */ /* Wait for either the response to be received or for timeout to - * occur. (1) net_lockedwait will also terminate if a signal is + * occur. (1) net_timedwait will also terminate if a signal is * received, (2) interrupts may be disabled! They will be re-enabled * while the task sleeps and automatically re-enabled when the task * restarts. */ - ninfo("Start time: 0x%08x\n", state.recv_time); - net_lockedwait(&state.recv_sem); + ret = net_timedwait(&state.recv_sem, _SO_TIMEOUT(psock->s_rcvtimeo)); + if (ret < 0) + { + state.recv_result = ret; + } icmpv6_callback_free(dev, conn, state.recv_cb); } diff --git a/net/icmpv6/icmpv6_rnotify.c b/net/icmpv6/icmpv6_rnotify.c index 38de50ea1f..d6ff6fa910 100644 --- a/net/icmpv6/icmpv6_rnotify.c +++ b/net/icmpv6/icmpv6_rnotify.c @@ -40,7 +40,6 @@ #include #include -#include #include #include #include @@ -266,46 +265,25 @@ int icmpv6_rwait_cancel(FAR struct icmpv6_rnotify_s *notify) * ****************************************************************************/ -int icmpv6_rwait(FAR struct icmpv6_rnotify_s *notify, - FAR struct timespec *timeout) +int icmpv6_rwait(FAR struct icmpv6_rnotify_s *notify, unsigned int timeout) { - struct timespec abstime; - irqstate_t flags; int ret; ninfo("Waiting...\n"); - /* And wait for the Neighbor Advertisement (or a timeout). Interrupts will - * be re-enabled while we wait. - */ + /* And wait for the Neighbor Advertisement (or a timeout). */ - flags = enter_critical_section(); - DEBUGVERIFY(clock_gettime(CLOCK_REALTIME, &abstime)); - - abstime.tv_sec += timeout->tv_sec; - abstime.tv_nsec += timeout->tv_nsec; - if (abstime.tv_nsec >= 1000000000) + ret = net_timedwait(¬ify->rn_sem, timeout); + if (ret >= 0) { - abstime.tv_sec++; - abstime.tv_nsec -= 1000000000; + ret = notify->rn_result; } - /* REVISIT: If net_timedwait() is awakened with signal, we will return - * the wrong error code. - */ - - net_timedwait(¬ify->rn_sem, &abstime); - ret = notify->rn_result; - /* Remove our wait structure from the list (we may no longer be at the * head of the list). */ icmpv6_rwait_cancel(notify); - - /* Re-enable interrupts and return the result of the wait */ - - leave_critical_section(flags); return ret; } diff --git a/net/icmpv6/icmpv6_sendto.c b/net/icmpv6/icmpv6_sendto.c index 353268a4ab..944865117d 100644 --- a/net/icmpv6/icmpv6_sendto.c +++ b/net/icmpv6/icmpv6_sendto.c @@ -86,9 +86,7 @@ struct icmpv6_sendto_s { FAR struct devif_callback_s *snd_cb; /* Reference to callback instance */ - FAR struct socket *snd_sock; /* IPPROTO_ICMP6 socket structure */ sem_t snd_sem; /* Use to manage the wait for send complete */ - clock_t snd_time; /* Start time for determining timeouts */ struct in6_addr snd_toaddr; /* The peer to send the request to */ FAR const uint8_t *snd_buf; /* ICMPv6 header + data payload */ uint16_t snd_buflen; /* Size of the ICMPv6 header + data payload */ @@ -99,46 +97,6 @@ struct icmpv6_sendto_s * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: sendto_timeout - * - * Description: - * Check for send timeout. - * - * Input Parameters: - * pstate - Reference to instance ot sendto state structure - * - * Returned Value: - * true: timeout false: no timeout - * - * Assumptions: - * The network is locked - * - ****************************************************************************/ - -#ifdef CONFIG_NET_SOCKOPTS -static inline int sendto_timeout(FAR struct icmpv6_sendto_s *pstate) -{ - FAR struct socket *psock; - - /* Check for a timeout configured via setsockopts(SO_SNDTIMEO). - * If none... we will let the send wait forever. - */ - - psock = pstate->snd_sock; - if (psock != NULL && psock->s_sndtimeo != 0) - { - /* Check if the configured timeout has elapsed */ - - return net_timeo(pstate->snd_time, psock->s_sndtimeo); - } - - /* No timeout */ - - return false; -} -#endif /* CONFIG_NET_SOCKOPTS */ - /**************************************************************************** * Name: sendto_request * @@ -279,41 +237,6 @@ static uint16_t sendto_eventhandler(FAR struct net_driver_s *dev, goto end_wait; } -#ifdef CONFIG_NET_SOCKOPTS - /* Check if the selected timeout has elapsed */ - - if (sendto_timeout(pstate)) - { - int failcode; - - /* Check if this device is on the same network as the destination - * device. - */ - - if (!net_ipv6addr_maskcmp(pstate->snd_toaddr.s6_addr16, - dev->d_ipv6addr, dev->d_ipv6netmask)) - { - /* Destination address was not on the local network served by this - * device. If a timeout occurs, then the most likely reason is - * that the destination address is not reachable. - */ - - nerr("ERROR: Not reachable\n"); - failcode = -ENETUNREACH; - } - else - { - nerr("ERROR: sendto() timeout\n"); - failcode = -ETIMEDOUT; - } - - /* Report the failure */ - - pstate->snd_result = failcode; - goto end_wait; - } -#endif - /* Continue waiting */ } @@ -436,7 +359,6 @@ ssize_t icmpv6_sendto(FAR struct socket *psock, FAR const void *buf, size_t len, nxsem_init(&state.snd_sem, 0, 0); nxsem_setprotocol(&state.snd_sem, SEM_PRIO_NONE); - state.snd_sock = psock; /* The IPPROTO_ICMP6 socket instance */ state.snd_result = -ENOMEM; /* Assume allocation failure */ state.snd_buf = buf; /* ICMPv6 header + data payload */ state.snd_buflen = len; /* Size of the ICMPv6 header+data payload */ @@ -445,7 +367,6 @@ ssize_t icmpv6_sendto(FAR struct socket *psock, FAR const void *buf, size_t len, inaddr->sin6_addr.s6_addr16); net_lock(); - state.snd_time = clock_systimer(); /* Set up the callback */ @@ -455,7 +376,6 @@ ssize_t icmpv6_sendto(FAR struct socket *psock, FAR const void *buf, size_t len, state.snd_cb->flags = (ICMPv6_POLL | NETDEV_DOWN); state.snd_cb->priv = (FAR void *)&state; state.snd_cb->event = sendto_eventhandler; - state.snd_result = -EINTR; /* Assume sem-wait interrupted by signal */ /* Setup to receive ICMPv6 ECHO replies */ @@ -465,18 +385,38 @@ ssize_t icmpv6_sendto(FAR struct socket *psock, FAR const void *buf, size_t len, conn->nreqs = 1; } - conn->dev = dev; + conn->dev = dev; /* Notify the device driver of the availability of TX data */ netdev_txnotify_dev(dev); /* Wait for either the send to complete or for timeout to occur. - * net_lockedwait will also terminate if a signal is received. + * net_timedwait will also terminate if a signal is received. */ - ninfo("Start time: 0x%08x\n", state.snd_time); - net_lockedwait(&state.snd_sem); + ret = net_timedwait(&state.snd_sem, _SO_TIMEOUT(psock->s_sndtimeo)); + if (ret < 0) + { + if (ret == -ETIMEDOUT) + { + /* Check if this device is on the same network as the destination + * device. + */ + + if (!net_ipv6addr_maskcmp(state.snd_toaddr.s6_addr16, + dev->d_ipv6addr, dev->d_ipv6netmask)) + { + /* Destination address was not on the local network served by + * this device. If a timeout occurs, then the most likely + * reason is that the destination address is not reachable. + */ + + ret = -ENETUNREACH; + } + } + state.snd_result = ret; + } icmpv6_callback_free(dev, conn, state.snd_cb); } diff --git a/net/ieee802154/ieee802154_recvfrom.c b/net/ieee802154/ieee802154_recvfrom.c index ee35d890b8..501f649820 100644 --- a/net/ieee802154/ieee802154_recvfrom.c +++ b/net/ieee802154/ieee802154_recvfrom.c @@ -49,7 +49,6 @@ #include -#include #include #include #include diff --git a/net/ieee802154/ieee802154_sendto.c b/net/ieee802154/ieee802154_sendto.c index b2f28cfa13..6ef9a313c7 100644 --- a/net/ieee802154/ieee802154_sendto.c +++ b/net/ieee802154/ieee802154_sendto.c @@ -51,7 +51,6 @@ #include -#include #include #include #include diff --git a/net/inet/inet.h b/net/inet/inet.h index 54adbde774..eef1f36986 100644 --- a/net/inet/inet.h +++ b/net/inet/inet.h @@ -301,7 +301,7 @@ int inet_close(FAR struct socket *psock); * * Parameters: * psock - Pointer to the socket structure instance - * abstime - The absolute time when the timeout will occur + * timeout - The relative time when the timeout will occur * * Returned Value: * Zero (OK) is returned on success; a negated error value is returned on @@ -309,9 +309,7 @@ int inet_close(FAR struct socket *psock); * ****************************************************************************/ -struct timespec; -int inet_txdrain(FAR struct socket *psock, - FAR const struct timespec *abstime); +int inet_txdrain(FAR struct socket *psock, unsigned int timeout); #undef EXTERN #if defined(__cplusplus) diff --git a/net/inet/inet_close.c b/net/inet/inet_close.c index 632483b2ed..0cd5d6cf6d 100644 --- a/net/inet/inet_close.c +++ b/net/inet/inet_close.c @@ -221,10 +221,6 @@ static inline int tcp_close_disconnect(FAR struct socket *psock) { struct tcp_close_s state; FAR struct tcp_conn_s *conn; -#ifdef CONFIG_NET_SOLINGER - struct timespec abstime; - bool linger; -#endif int ret = OK; /* Interrupts are disabled here to avoid race conditions */ @@ -247,31 +243,18 @@ static inline int tcp_close_disconnect(FAR struct socket *psock) * state of the option and linger interval. */ - linger = _SO_GETOPT(psock->s_options, SO_LINGER); - if (linger) + if (_SO_GETOPT(psock->s_options, SO_LINGER)) { - /* Get the current time */ + /* Wait until for the buffered TX data to be sent. */ - ret = clock_gettime(CLOCK_REALTIME, &abstime); - if (ret >= 0) + ret = tcp_txdrain(psock, _SO_TIMEOUT(psock->s_linger)); + if (ret < 0) { - /* NOTE: s_linger's unit is deciseconds so we don't need to update - * abstime.tv_nsec here. + /* tcp_txdrain may fail, but that won't stop us from closing + * the socket. */ - abstime.tv_sec += psock->s_linger / DSEC_PER_SEC; - - /* Wait until abstime for the buffered TX data to be sent. */ - - ret = tcp_txdrain(psock, &abstime); - if (ret < 0) - { - /* tcp_txdrain may fail, but that won't stop us from closing - * the socket. - */ - - nerr("ERROR: tcp_txdrain() failed: %d\n", ret); - } + nerr("ERROR: tcp_txdrain() failed: %d\n", ret); } } #endif @@ -376,10 +359,6 @@ static inline int tcp_close_disconnect(FAR struct socket *psock) static inline int udp_close(FAR struct socket *psock) { FAR struct udp_conn_s *conn; -#ifdef CONFIG_NET_SOLINGER - struct timespec abstime; - bool linger; -#endif /* Interrupts are disabled here to avoid race conditions */ @@ -401,33 +380,20 @@ static inline int udp_close(FAR struct socket *psock) * state of the option and linger interval. */ - linger = _SO_GETOPT(psock->s_options, SO_LINGER); - if (linger) + if (_SO_GETOPT(psock->s_options, SO_LINGER)) { int ret; - /* Get the current time */ + /* Wait until for the buffered TX data to be sent. */ - ret = clock_gettime(CLOCK_REALTIME, &abstime); - if (ret >= 0) + ret = udp_txdrain(psock, _SO_TIMEOUT(psock->s_linger)); + if (ret < 0) { - /* NOTE: s_linger's unit is deciseconds so we don't need to update - * abstime.tv_nsec here. + /* udp_txdrain may fail, but that won't stop us from closing + * the socket. */ - abstime.tv_sec += psock->s_linger / DSEC_PER_SEC; - - /* Wait until abstime for the buffered TX data to be sent. */ - - ret = udp_txdrain(psock, &abstime); - if (ret < 0) - { - /* udp_txdrain may fail, but that won't stop us from closing - * the socket. - */ - - nerr("ERROR: udp_txdrain() failed: %d\n", ret); - } + nerr("ERROR: udp_txdrain() failed: %d\n", ret); } } #endif diff --git a/net/inet/inet_recvfrom.c b/net/inet/inet_recvfrom.c index 458fab24b2..b217cca0f6 100644 --- a/net/inet/inet_recvfrom.c +++ b/net/inet/inet_recvfrom.c @@ -51,7 +51,6 @@ #include -#include #include #include #include @@ -92,9 +91,6 @@ struct inet_recvfrom_s { FAR struct socket *ir_sock; /* The parent socket structure */ -#ifdef CONFIG_NET_SOCKOPTS - clock_t ir_starttime; /* rcv start time for determining timeout */ -#endif FAR struct devif_callback_s *ir_cb; /* Reference to callback instance */ sem_t ir_sem; /* Semaphore signals recv completion */ size_t ir_buflen; /* Length of receive buffer */ @@ -335,7 +331,7 @@ static inline void inet_tcp_readahead(struct inet_recvfrom_s *pstate) inet_update_recvlen(pstate, recvlen); - /* If we took all of the ata from the I/O buffer chain is empty, then + /* If we took all of the data from the I/O buffer chain is empty, then * release it. If there is still data available in the I/O buffer * chain, then just trim the data that we have taken from the * beginning of the I/O buffer chain. @@ -459,60 +455,6 @@ out: } #endif -/**************************************************************************** - * Name: inet_recvfrom_timeout - * - * Description: - * Check for recvfrom timeout. - * - * Input Parameters: - * pstate recvfrom state structure - * - * Returned Value: - * TRUE:timeout FALSE:no timeout - * - * Assumptions: - * The network is locked. - * - ****************************************************************************/ - -#if defined(NET_UDP_HAVE_STACK) || defined(NET_TCP_HAVE_STACK) -#ifdef CONFIG_NET_SOCKOPTS -static int inet_recvfrom_timeout(struct inet_recvfrom_s *pstate) -{ - FAR struct socket *psock = 0; - socktimeo_t timeo = 0; - - /* Check for a timeout configured via setsockopts(SO_RCVTIMEO). If none... - * we well let the read hang forever (except for the special case below). - */ - - /* Get the socket reference from the private data */ - - psock = pstate->ir_sock; - if (psock) - { - /* Recover the timeout value (zero if no timeout) */ - - timeo = psock->s_rcvtimeo; - } - - /* Is there an effective timeout? */ - - if (timeo) - { - /* Yes.. Check if the timeout has elapsed */ - - return net_timeo(pstate->ir_starttime, timeo); - } - - /* No timeout -- hang forever waiting for data. */ - - return FALSE; -} -#endif /* CONFIG_NET_SOCKOPTS */ -#endif /* NET_UDP_HAVE_STACK || NET_TCP_HAVE_STACK */ - /**************************************************************************** * Name: inet_tcp_sender * @@ -676,14 +618,6 @@ static uint16_t inet_tcp_eventhandler(FAR struct net_driver_s *dev, nxsem_post(&pstate->ir_sem); } - -#ifdef CONFIG_NET_SOCKOPTS - /* Reset the timeout. We will want a short timeout to terminate - * the TCP receive. - */ - - pstate->ir_starttime = clock_systimer(); -#endif } /* Check for a loss of connection. @@ -734,36 +668,6 @@ static uint16_t inet_tcp_eventhandler(FAR struct net_driver_s *dev, nxsem_post(&pstate->ir_sem); } - -#ifdef CONFIG_NET_SOCKOPTS - /* No data has been received -- this is some other event... probably a - * poll -- check for a timeout. - */ - - else if (inet_recvfrom_timeout(pstate)) - { - /* Yes.. the timeout has elapsed... do not allow any further - * callbacks - */ - - ninfo("TCP timeout\n"); - - pstate->ir_cb->flags = 0; - pstate->ir_cb->priv = NULL; - pstate->ir_cb->event = NULL; - - /* Report the timeout error */ - - pstate->ir_result = -EAGAIN; - - /* Wake up the waiting thread, returning either the error -EAGAIN - * that signals the timeout event or the data received up to - * the point that the timeout occurred (no error). - */ - - nxsem_post(&pstate->ir_sem); - } -#endif /* CONFIG_NET_SOCKOPTS */ } return flags; @@ -977,25 +881,6 @@ static uint16_t inet_udp_eventhandler(FAR struct net_driver_s *dev, flags &= ~UDP_NEWDATA; } - -#ifdef CONFIG_NET_SOCKOPTS - /* No data has been received -- this is some other event... probably a - * poll -- check for a timeout. - */ - - else if (inet_recvfrom_timeout(pstate)) - { - /* Yes.. the timeout has elapsed... do not allow any further - * callbacks - */ - - nerr("ERROR: UDP timeout\n"); - - /* Terminate the transfer with an -EAGAIN error */ - - inet_udp_terminate(pstate, -EAGAIN); - } -#endif /* CONFIG_NET_SOCKOPTS */ } return flags; @@ -1046,9 +931,6 @@ static void inet_recvfrom_initialize(FAR struct socket *psock, FAR void *buf, /* Set up the start time for the timeout */ pstate->ir_sock = psock; -#ifdef CONFIG_NET_SOCKOPTS - pstate->ir_starttime = clock_systimer(); -#endif } /* The only un-initialization that has to be performed is destroying the @@ -1066,7 +948,7 @@ static void inet_recvfrom_initialize(FAR struct socket *psock, FAR void *buf, * Evaluate the result of the recv operations * * Input Parameters: - * result The result of the net_lockedwait operation (may indicate EINTR) + * result The result of the net_timedwait operation (may indicate EINTR) * pstate A pointer to the state structure to be initialized * * Returned Value: @@ -1092,8 +974,8 @@ static ssize_t inet_recvfrom_result(int result, struct inet_recvfrom_s *pstate) return pstate->ir_result; } - /* If net_lockedwait failed, then we were probably reawakened by a signal. In - * this case, net_lockedwait will have returned negated errno appropriately. + /* If net_timedwait failed, then we were probably reawakened by a signal. In + * this case, net_timedwait will have returned negated errno appropriately. */ if (result < 0) @@ -1199,11 +1081,11 @@ static ssize_t inet_udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t state.ir_cb->event = inet_udp_eventhandler; /* Wait for either the receive to complete or for an error/timeout - * to occur. net_lockedwait will also terminate if a signal is + * to occur. net_timedwait will also terminate if a signal is * received. */ - ret = net_lockedwait(&state. ir_sem); + ret = net_timedwait(&state. ir_sem, _SO_TIMEOUT(psock->s_rcvtimeo)); /* Make sure that no further events are processed */ @@ -1349,11 +1231,11 @@ static ssize_t inet_tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t state.ir_cb->event = inet_tcp_eventhandler; /* Wait for either the receive to complete or for an error/timeout - * to occur. net_lockedwait will also terminate if a signal isi + * to occur. net_timedwait will also terminate if a signal isi * received. */ - ret = net_lockedwait(&state.ir_sem); + ret = net_timedwait(&state.ir_sem, _SO_TIMEOUT(psock->s_rcvtimeo)); /* Make sure that no further events are processed */ diff --git a/net/inet/inet_txdrain.c b/net/inet/inet_txdrain.c index ca3fc37d9b..f1d0cade7a 100644 --- a/net/inet/inet_txdrain.c +++ b/net/inet/inet_txdrain.c @@ -64,7 +64,7 @@ * * Parameters: * psock - Pointer to the socket structure instance - * abstime - The absolute time when the timeout will occur + * timeout - The relative time when the timeout will occur * * Returned Value: * Zero (OK) is returned on success; a negated error value is returned on @@ -72,8 +72,7 @@ * ****************************************************************************/ -int inet_txdrain(FAR struct socket *psock, - FAR const struct timespec *abstime) +int inet_txdrain(FAR struct socket *psock, unsigned int timeout) { int ret = OK; @@ -86,7 +85,7 @@ int inet_txdrain(FAR struct socket *psock, #if defined(NET_TCP_HAVE_STACK) case SOCK_STREAM: { - ret = tcp_txdrain(psock, abstime); + ret = tcp_txdrain(psock, timeout); } break; #endif @@ -94,7 +93,7 @@ int inet_txdrain(FAR struct socket *psock, #if defined(NET_UDP_HAVE_STACK) case SOCK_DGRAM: { - ret = udp_txdrain(psock, abstime); + ret = udp_txdrain(psock, timeout); } break; #endif diff --git a/net/neighbor/neighbor.h b/net/neighbor/neighbor.h index 64c30fc2f4..508837feab 100644 --- a/net/neighbor/neighbor.h +++ b/net/neighbor/neighbor.h @@ -49,7 +49,6 @@ #include -#include #include #include #include diff --git a/net/neighbor/neighbor_globals.c b/net/neighbor/neighbor_globals.c index e8c0587806..175cbc63f5 100644 --- a/net/neighbor/neighbor_globals.c +++ b/net/neighbor/neighbor_globals.c @@ -42,7 +42,6 @@ ****************************************************************************/ #include -#include #include "neighbor/neighbor.h" diff --git a/net/pkt/pkt_recvfrom.c b/net/pkt/pkt_recvfrom.c index 70f99de3e6..5c8912ca73 100644 --- a/net/pkt/pkt_recvfrom.c +++ b/net/pkt/pkt_recvfrom.c @@ -51,7 +51,6 @@ #include -#include #include #include #include diff --git a/net/pkt/pkt_send.c b/net/pkt/pkt_send.c index 71e3436bcc..571886f923 100644 --- a/net/pkt/pkt_send.c +++ b/net/pkt/pkt_send.c @@ -51,7 +51,6 @@ #include -#include #include #include #include diff --git a/net/sixlowpan/sixlowpan_internal.h b/net/sixlowpan/sixlowpan_internal.h index d97b4707ce..5305291864 100644 --- a/net/sixlowpan/sixlowpan_internal.h +++ b/net/sixlowpan/sixlowpan_internal.h @@ -267,7 +267,7 @@ struct iob_s; /* Forward reference */ * buf - Data to send * len - Length of data to send * destmac - The IEEE802.15.4 MAC address of the destination - * timeout - Send timeout in deciseconds + * timeout - Send timeout in milliseconds * * Returned Value: * Ok is returned on success; Othewise a negated errno value is returned. diff --git a/net/sixlowpan/sixlowpan_reassbuf.c b/net/sixlowpan/sixlowpan_reassbuf.c index a2a9936e6f..4e124e0fe3 100644 --- a/net/sixlowpan/sixlowpan_reassbuf.c +++ b/net/sixlowpan/sixlowpan_reassbuf.c @@ -46,7 +46,6 @@ #include #include -#include #include #include @@ -162,7 +161,7 @@ static void sixlowpan_reass_expire(void) /* If the reassembly has expired, then free the reassembly buffer */ - if (elapsed > NET_6LOWPAN_TIMEOUT) + if (elapsed >= NET_6LOWPAN_TIMEOUT) { nwarn("WARNING: Reassembly timed out\n"); sixlowpan_reass_free(reass); diff --git a/net/sixlowpan/sixlowpan_send.c b/net/sixlowpan/sixlowpan_send.c index 13b76495da..930f809509 100644 --- a/net/sixlowpan/sixlowpan_send.c +++ b/net/sixlowpan/sixlowpan_send.c @@ -44,7 +44,6 @@ #include #include -#include #include #include #include @@ -81,8 +80,6 @@ struct sixlowpan_send_s FAR struct devif_callback_s *s_cb; /* Reference to callback instance */ sem_t s_waitsem; /* Supports waiting for driver events */ int s_result; /* The result of the transfer */ - uint16_t s_timeout; /* Send timeout in deciseconds */ - clock_t s_time; /* Last send time for determining timeout */ FAR const struct ipv6_hdr_s *s_ipv6hdr; /* IPv6 header, followed by UDP or ICMP header. */ FAR const struct netdev_varaddr_s *s_destmac; /* Destination MAC address */ FAR const void *s_buf; /* Data to send */ @@ -93,47 +90,6 @@ struct sixlowpan_send_s * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: send_timeout - * - * Description: - * Check for send timeout. - * - * Input Parameters: - * sinfo - Send state structure reference - * - * Returned Value: - * TRUE:timeout FALSE:no timeout - * - * Assumptions: - * The network is locked - * - ****************************************************************************/ - -static inline bool send_timeout(FAR struct sixlowpan_send_s *sinfo) -{ - /* Check for a timeout. Zero means none and, in that case, we will let - * the send wait forever. - */ - - if (sinfo->s_timeout != 0) - { - /* Check if the configured timeout has elapsed */ - - clock_t timeo_ticks = DSEC2TICK(sinfo->s_timeout); - clock_t elapsed = clock_systimer() - sinfo->s_time; - - if (elapsed >= timeo_ticks) - { - return true; - } - } - - /* No timeout */ - - return false; -} - /**************************************************************************** * Name: send_eventhandler * @@ -203,18 +159,6 @@ static uint16_t send_eventhandler(FAR struct net_driver_s *dev, goto end_wait; } - /* Check for a timeout. */ - - if (send_timeout(sinfo)) - { - /* Yes.. report the timeout */ - - nwarn("WARNING: SEND timeout\n"); - sinfo->s_result = -ETIMEDOUT; - neighbor_notreachable(dev); - goto end_wait; - } - /* Continue waiting */ return flags; @@ -257,7 +201,7 @@ end_wait: * buf - Data to send * len - Length of data to send * destmac - The IEEE802.15.4 MAC address of the destination - * timeout - Send timeout in deciseconds + * timeout - Send timeout in milliseconds * * Returned Value: * Ok is returned on success; Othewise a negated errno value is returned. @@ -286,8 +230,6 @@ int sixlowpan_send(FAR struct net_driver_s *dev, nxsem_setprotocol(&sinfo.s_waitsem, SEM_PRIO_NONE); sinfo.s_result = -EBUSY; - sinfo.s_timeout = timeout; - sinfo.s_time = clock_systimer(); sinfo.s_ipv6hdr = ipv6hdr; sinfo.s_destmac = destmac; sinfo.s_buf = buf; @@ -318,14 +260,18 @@ int sixlowpan_send(FAR struct net_driver_s *dev, netdev_txnotify_dev(dev); /* Wait for the send to complete or an error to occur. - * net_lockedwait will also terminate if a signal is received. + * net_timedwait will also terminate if a signal is received. */ ninfo("Wait for send complete\n"); - ret = net_lockedwait(&sinfo.s_waitsem); + ret = net_timedwait(&sinfo.s_waitsem, timeout); if (ret < 0) { + if (ret == -ETIMEDOUT) + { + neighbor_notreachable(dev); + } sinfo.s_result = ret; } diff --git a/net/sixlowpan/sixlowpan_tcpsend.c b/net/sixlowpan/sixlowpan_tcpsend.c index 3b695cdcdc..dc7b51cfad 100644 --- a/net/sixlowpan/sixlowpan_tcpsend.c +++ b/net/sixlowpan/sixlowpan_tcpsend.c @@ -94,8 +94,6 @@ struct sixlowpan_send_s FAR struct devif_callback_s *s_cb; /* Reference to callback instance */ sem_t s_waitsem; /* Supports waiting for driver events */ int s_result; /* The result of the transfer */ - uint16_t s_timeout; /* Send timeout in deciseconds */ - clock_t s_time; /* Last send time for determining timeout */ FAR const struct netdev_varaddr_s *s_destmac; /* Destination MAC address */ FAR const uint8_t *s_buf; /* Data to send */ size_t s_buflen; /* Length of data in buf */ @@ -287,47 +285,6 @@ static int sixlowpan_tcp_header(FAR struct tcp_conn_s *conn, return OK; } -/**************************************************************************** - * Name: send_timeout - * - * Description: - * Check for send timeout. - * - * Input Parameters: - * sinfo - Send state structure reference - * - * Returned Value: - * TRUE:timeout FALSE:no timeout - * - * Assumptions: - * The network is locked - * - ****************************************************************************/ - -static inline bool send_timeout(FAR struct sixlowpan_send_s *sinfo) -{ - /* Check for a timeout. Zero means none and, in that case, we will let - * the send wait forever. - */ - - if (sinfo->s_timeout != 0) - { - /* Check if the configured timeout has elapsed */ - - clock_t timeo_ticks = DSEC2TICK(sinfo->s_timeout); - clock_t elapsed = clock_systimer() - sinfo->s_time; - - if (elapsed >= timeo_ticks) - { - return true; - } - } - - /* No timeout */ - - return false; -} - /**************************************************************************** * Name: tcp_send_eventhandler * @@ -398,12 +355,6 @@ static uint16_t tcp_send_eventhandler(FAR struct net_driver_s *dev, { FAR struct tcp_hdr_s *tcp = TCPBUF(dev); -#ifdef CONFIG_NET_SOCKOPTS - /* Update the timeout */ - - sinfo->s_time = clock_systimer(); -#endif - /* The current acknowledgement number number is the (relative) offset * of the of the next byte needed by the receiver. The s_isn is the * offset of the first byte to send to the receiver. The difference @@ -583,21 +534,6 @@ static uint16_t tcp_send_eventhandler(FAR struct net_driver_s *dev, } } -#ifdef CONFIG_NET_SOCKOPTS - /* All data has been sent and we are just waiting for ACK or re-transmit - * indications to complete the send. Check for a timeout. - */ - - if (send_timeout(sinfo)) - { - /* Yes.. report the timeout */ - - nwarn("WARNING: SEND timeout\n"); - sinfo->s_sent = -ETIMEDOUT; - goto end_wait; - } -#endif /* CONFIG_NET_SOCKOPTS */ - /* Continue waiting */ return flags; @@ -640,7 +576,7 @@ end_wait: * buf - Data to send * len - Length of data to send * destmac - The IEEE802.15.4 MAC address of the destination - * timeout - Send timeout in deciseconds + * timeout - Send timeout in milliseconds * * Returned Value: * Ok is returned on success; Othewise a negated errno value is returned. @@ -689,8 +625,6 @@ static int sixlowpan_send_packet(FAR struct socket *psock, sinfo.s_sock = psock; sinfo.s_result = -EBUSY; - sinfo.s_timeout = timeout; - sinfo.s_time = clock_systimer(); sinfo.s_destmac = destmac; sinfo.s_buf = buf; sinfo.s_buflen = len; @@ -717,12 +651,22 @@ static int sixlowpan_send_packet(FAR struct socket *psock, netdev_txnotify_dev(dev); /* Wait for the send to complete or an error to occur. - * net_lockedwait will also terminate if a signal is received. + * net_timedwait will also terminate if a signal is received. */ ninfo("Wait for send complete\n"); - ret = net_lockedwait(&sinfo.s_waitsem); + for (; ; ) + { + uint32_t acked = sinfo.s_acked; + + ret = net_timedwait(&sinfo.s_waitsem, timeout); + if (ret != -ETIMEDOUT || acked == sinfo.s_acked) + { + break; /* Timeout without any progress */ + } + } + if (ret < 0) { sinfo.s_result = ret; @@ -773,7 +717,6 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf, FAR struct tcp_conn_s *conn; FAR struct net_driver_s *dev; struct netdev_varaddr_s destmac; - uint16_t timeout; int ret; ninfo("buflen %lu\n", (unsigned long)buflen); @@ -859,14 +802,8 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf, * packet buffer. */ -#ifdef CONFIG_NET_SOCKOPTS - timeout = psock->s_sndtimeo; -#else - timeout = 0; -#endif - ret = sixlowpan_send_packet(psock, dev, conn, buf, buflen, &destmac, - timeout); + _SO_TIMEOUT(psock->s_sndtimeo)); if (ret < 0) { nerr("ERROR: sixlowpan_send_packet() failed: %d\n", ret); diff --git a/net/sixlowpan/sixlowpan_udpsend.c b/net/sixlowpan/sixlowpan_udpsend.c index 1d111a2cd9..bcbe482f64 100644 --- a/net/sixlowpan/sixlowpan_udpsend.c +++ b/net/sixlowpan/sixlowpan_udpsend.c @@ -167,7 +167,6 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock, struct ipv6udp_hdr_s ipv6udp; struct netdev_varaddr_s destmac; uint16_t iplen; - uint16_t timeout; int ret; ninfo("buflen %lu\n", (unsigned long)buflen); @@ -306,15 +305,9 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock, * packet. */ -#ifdef CONFIG_NET_SOCKOPTS - timeout = psock->s_sndtimeo; -#else - timeout = 0; -#endif - ret = sixlowpan_send(dev, &conn->list, (FAR const struct ipv6_hdr_s *)&ipv6udp, - buf, buflen, &destmac, timeout); + buf, buflen, &destmac, _SO_TIMEOUT(psock->s_sndtimeo)); if (ret < 0) { nerr("ERROR: sixlowpan_send() failed: %d\n", ret); diff --git a/net/socket/socket.h b/net/socket/socket.h index 4359c1cc76..a2452f2e6e 100644 --- a/net/socket/socket.h +++ b/net/socket/socket.h @@ -121,6 +121,14 @@ #define _SO_GETVALID(o) (((unsigned int)(o)) <= _SO_MAXOPT) #define _SO_SETVALID(o) ((((unsigned int)(o)) <= _SO_MAXOPT) && !_SO_GETONLY(o)) +/* Macros to convert timeout value */ + +#ifdef CONFIG_NET_SOCKOPTS +#define _SO_TIMEOUT(t) ((t) ? (t) * MSEC_PER_DSEC : UINT_MAX) +#else +#define _SO_TIMEOUT(t) (UINT_MAX) +#endif /* CONFIG_NET_SOCKOPTS */ + /* Macro to set socket errors */ #ifdef CONFIG_NET_SOCKOPTS diff --git a/net/tcp/tcp.h b/net/tcp/tcp.h index 5253018974..af62daba4e 100644 --- a/net/tcp/tcp.h +++ b/net/tcp/tcp.h @@ -1455,7 +1455,6 @@ void tcp_wrbuffer_initialize(void); #ifdef CONFIG_NET_TCP_WRITE_BUFFERS struct tcp_wrbuffer_s; - FAR struct tcp_wrbuffer_s *tcp_wrbuffer_alloc(void); /**************************************************************************** @@ -1760,7 +1759,7 @@ void tcp_disconnect_signal(FAR struct tcp_conn_s *conn); * * Input Parameters: * psock - An instance of the internal socket structure. - * abstime - The absolute time when the timeout will occur + * timeout - The relative time when the timeout will occur * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned @@ -1769,11 +1768,9 @@ void tcp_disconnect_signal(FAR struct tcp_conn_s *conn); ****************************************************************************/ #if defined(CONFIG_NET_TCP_WRITE_BUFFERS) && defined(CONFIG_NET_TCP_NOTIFIER) -struct timespec; -int tcp_txdrain(FAR struct socket *psock, - FAR const struct timespec *abstime); +int tcp_txdrain(FAR struct socket *psock, unsigned int timeout); #else -# define tcp_txdrain(conn, abstime) (0) +# define tcp_txdrain(conn, timeout) (0) #endif #undef EXTERN diff --git a/net/tcp/tcp_conn.c b/net/tcp/tcp_conn.c index 180094e51c..2c22246af9 100644 --- a/net/tcp/tcp_conn.c +++ b/net/tcp/tcp_conn.c @@ -54,7 +54,6 @@ #include -#include #include #include #include diff --git a/net/tcp/tcp_getsockopt.c b/net/tcp/tcp_getsockopt.c index c07a488873..ee4963aa03 100644 --- a/net/tcp/tcp_getsockopt.c +++ b/net/tcp/tcp_getsockopt.c @@ -39,7 +39,6 @@ #include -#include #include #include #include diff --git a/net/tcp/tcp_input.c b/net/tcp/tcp_input.c index db718be9df..7acf298cc5 100644 --- a/net/tcp/tcp_input.c +++ b/net/tcp/tcp_input.c @@ -51,7 +51,6 @@ #include #include -#include #include #include #include diff --git a/net/tcp/tcp_send_buffered.c b/net/tcp/tcp_send_buffered.c index 262d10a471..76d4af2a9c 100644 --- a/net/tcp/tcp_send_buffered.c +++ b/net/tcp/tcp_send_buffered.c @@ -62,7 +62,6 @@ #include #include -#include #include #include #include diff --git a/net/tcp/tcp_send_unbuffered.c b/net/tcp/tcp_send_unbuffered.c index 1a77821214..1d9b502835 100644 --- a/net/tcp/tcp_send_unbuffered.c +++ b/net/tcp/tcp_send_unbuffered.c @@ -54,7 +54,6 @@ #include -#include #include #include #include @@ -108,9 +107,6 @@ struct send_s ssize_t snd_sent; /* The number of bytes sent */ uint32_t snd_isn; /* Initial sequence number */ uint32_t snd_acked; /* The number of bytes acked */ -#ifdef CONFIG_NET_SOCKOPTS - clock_t snd_time; /* Last send time for determining timeout */ -#endif #if defined(CONFIG_NET_TCP_SPLIT) bool snd_odd; /* True: Odd packet in pair transaction */ #endif @@ -120,46 +116,6 @@ struct send_s * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: send_timeout - * - * Description: - * Check for send timeout. - * - * Input Parameters: - * pstate send state structure - * - * Returned Value: - * TRUE:timeout FALSE:no timeout - * - * Assumptions: - * The network is locked. - * - ****************************************************************************/ - -#ifdef CONFIG_NET_SOCKOPTS -static inline int send_timeout(FAR struct send_s *pstate) -{ - FAR struct socket *psock; - - /* Check for a timeout configured via setsockopts(SO_SNDTIMEO). - * If none... we will let the send wait forever. - */ - - psock = pstate->snd_sock; - if (psock && psock->s_sndtimeo != 0) - { - /* Check if the configured timeout has elapsed */ - - return net_timeo(pstate->snd_time, psock->s_sndtimeo); - } - - /* No timeout */ - - return FALSE; -} -#endif /* CONFIG_NET_SOCKOPTS */ - /**************************************************************************** * Name: tcpsend_ipselect * @@ -251,12 +207,6 @@ static uint16_t tcpsend_eventhandler(FAR struct net_driver_s *dev, { FAR struct tcp_hdr_s *tcp; - /* Update the timeout */ - -#ifdef CONFIG_NET_SOCKOPTS - pstate->snd_time = clock_systimer(); -#endif - /* Get the offset address of the TCP header */ #ifdef CONFIG_NET_IPv4 @@ -503,21 +453,6 @@ static uint16_t tcpsend_eventhandler(FAR struct net_driver_s *dev, } } -#ifdef CONFIG_NET_SOCKOPTS - /* All data has been sent and we are just waiting for ACK or re-transmit - * indications to complete the send. Check for a timeout. - */ - - if (send_timeout(pstate)) - { - /* Yes.. report the timeout */ - - nwarn("WARNING: SEND timeout\n"); - pstate->snd_sent = -ETIMEDOUT; - goto end_wait; - } -#endif /* CONFIG_NET_SOCKOPTS */ - /* Continue waiting */ return flags; @@ -734,6 +669,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock, { /* Allocate resources to receive a callback */ + ret = -ENOMEM; /* Assume allocation failure */ state.snd_cb = tcp_callback_alloc(conn); if (state.snd_cb) { @@ -747,11 +683,6 @@ ssize_t psock_tcp_send(FAR struct socket *psock, conn->tx_unacked = 0; - /* Set the initial time for calculating timeouts */ - -#ifdef CONFIG_NET_SOCKOPTS - state.snd_time = clock_systimer(); -#endif /* Set up the callback in the connection */ state.snd_cb->flags = (TCP_ACKDATA | TCP_REXMIT | TCP_POLL | @@ -767,7 +698,17 @@ ssize_t psock_tcp_send(FAR struct socket *psock, * net_lockedwait will also terminate if a signal is received. */ - ret = net_lockedwait(&state.snd_sem); + for (; ; ) + { + uint32_t acked = state.snd_acked; + + ret = net_timedwait(&state.snd_sem, + _SO_TIMEOUT(psock->s_sndtimeo)); + if (ret != -ETIMEOUT || acked == state.snd_acked) + { + break; /* Timeout without any progress */ + } + } /* Make sure that no further events are processed */ @@ -788,8 +729,8 @@ ssize_t psock_tcp_send(FAR struct socket *psock, goto errout; } - /* If net_lockedwait failed, then we were probably reawakened by a signal. - * In this case, net_lockedwait will have returned negated errno + /* If net_timedwait failed, then we were probably reawakened by a signal. + * In this case, net_timedwait will have returned negated errno * appropriately. */ diff --git a/net/tcp/tcp_sendfile.c b/net/tcp/tcp_sendfile.c index c7fcaed41b..d5cbba0b1f 100644 --- a/net/tcp/tcp_sendfile.c +++ b/net/tcp/tcp_sendfile.c @@ -55,7 +55,6 @@ #include #include -#include #include #include #include @@ -105,55 +104,12 @@ struct sendfile_s ssize_t snd_sent; /* The number of bytes sent */ uint32_t snd_isn; /* Initial sequence number */ uint32_t snd_acked; /* The number of bytes acked */ -#ifdef CONFIG_NET_SOCKOPTS - clock_t snd_time; /* Last send time for determining timeout */ -#endif }; /**************************************************************************** * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: sendfile_timeout - * - * Description: - * Check for send timeout. - * - * Input Parameters: - * pstate - send state structure - * - * Returned Value: - * TRUE:timeout FALSE:no timeout - * - * Assumptions: - * The network is locked - * - ****************************************************************************/ - -#ifdef CONFIG_NET_SOCKOPTS -static inline int sendfile_timeout(FAR struct sendfile_s *pstate) -{ - FAR struct socket *psock = 0; - - /* Check for a timeout configured via setsockopts(SO_SNDTIMEO). - * If none... we well let the send wait forever. - */ - - psock = pstate->snd_sock; - if (psock && psock->s_sndtimeo != 0) - { - /* Check if the configured timeout has elapsed */ - - return net_timeo(pstate->snd_time, psock->s_sndtimeo); - } - - /* No timeout */ - - return FALSE; -} -#endif /* CONFIG_NET_SOCKOPTS */ - static uint16_t ack_eventhandler(FAR struct net_driver_s *dev, FAR void *pvconn, FAR void *pvpriv, uint16_t flags) @@ -166,12 +122,6 @@ static uint16_t ack_eventhandler(FAR struct net_driver_s *dev, { FAR struct tcp_hdr_s *tcp; -#ifdef CONFIG_NET_SOCKOPTS - /* Update the timeout */ - - pstate->snd_time = clock_systimer(); -#endif - /* Get the offset address of the TCP header */ #ifdef CONFIG_NET_IPv6 @@ -179,7 +129,7 @@ static uint16_t ack_eventhandler(FAR struct net_driver_s *dev, if (IFF_IS_IPv6(dev->d_flags)) #endif { - DEBUGASSERT(pstate->snd_sock == PF_INET6); + DEBUGASSERT(pstate->snd_sock->s_domain == PF_INET6); tcp = TCPIPv6BUF; } #endif /* CONFIG_NET_IPv6 */ @@ -189,7 +139,7 @@ static uint16_t ack_eventhandler(FAR struct net_driver_s *dev, else #endif { - DEBUGASSERT(pstate->snd_sock == PF_INET); + DEBUGASSERT(pstate->snd_sock->s_domain == PF_INET); tcp = TCPIPv4BUF; } #endif /* CONFIG_NET_IPv4 */ @@ -401,21 +351,6 @@ static uint16_t sendfile_eventhandler(FAR struct net_driver_s *dev, } } -#ifdef CONFIG_NET_SOCKOPTS - /* All data has been send and we are just waiting for ACK or re-transmit - * indications to complete the send. Check for a timeout. - */ - - if (sendfile_timeout(pstate)) - { - /* Yes.. report the timeout */ - - nwarn("WARNING: SEND timeout\n"); - pstate->snd_sent = -ETIMEDOUT; - goto end_wait; - } -#endif /* CONFIG_NET_SOCKOPTS */ - if (pstate->snd_sent >= pstate->snd_flen && pstate->snd_acked < pstate->snd_flen) { @@ -612,12 +547,6 @@ ssize_t tcp_sendfile(FAR struct socket *psock, FAR struct file *infile, conn->tx_unacked = 0; -#ifdef CONFIG_NET_SOCKOPTS - /* Set the initial time for calculating timeouts */ - - state.snd_time = clock_systimer(); -#endif - /* Set up the ACK callback in the connection */ state.snd_ackcb->flags = (TCP_ACKDATA | TCP_REXMIT | TCP_DISCONN_EVENTS); @@ -626,18 +555,25 @@ ssize_t tcp_sendfile(FAR struct socket *psock, FAR struct file *infile, /* Perform the TCP send operation */ - do + state.snd_datacb->flags = TCP_POLL; + state.snd_datacb->priv = (FAR void *)&state; + state.snd_datacb->event = sendfile_eventhandler; + + /* Notify the device driver of the availability of TX data */ + + sendfile_txnotify(psock, conn); + + for (; ; ) { - state.snd_datacb->flags = TCP_POLL; - state.snd_datacb->priv = (FAR void *)&state; - state.snd_datacb->event = sendfile_eventhandler; + uint32_t acked = state.snd_acked; - /* Notify the device driver of the availability of TX data */ - - sendfile_txnotify(psock, conn); - net_lockedwait(&state.snd_sem); + ret = net_timedwait_uninterruptible(&state.snd_sem, + _SO_TIMEOUT(psock->s_sndtimeo)); + if (ret != -ETIMEDOUT || acked == state.snd_acked) + { + break; /* Timeout without any progress */ + } } - while (state.snd_sent >= 0 && state.snd_acked < state.snd_flen); tcp_callback_free(conn, state.snd_ackcb); diff --git a/net/tcp/tcp_setsockopt.c b/net/tcp/tcp_setsockopt.c index 369c6d47a6..e6760eaec9 100644 --- a/net/tcp/tcp_setsockopt.c +++ b/net/tcp/tcp_setsockopt.c @@ -39,7 +39,6 @@ #include -#include #include #include #include @@ -47,7 +46,6 @@ #include -#include #include #include diff --git a/net/tcp/tcp_txdrain.c b/net/tcp/tcp_txdrain.c index dfd9d14fd9..3c90470c50 100644 --- a/net/tcp/tcp_txdrain.c +++ b/net/tcp/tcp_txdrain.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include @@ -91,7 +90,7 @@ static void txdrain_worker(FAR void *arg) * * Input Parameters: * psock - An instance of the internal socket structure. - * abstime - The absolute time when the timeout will occur + * timeout - The relative time when the timeout will occur * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned @@ -99,8 +98,7 @@ static void txdrain_worker(FAR void *arg) * ****************************************************************************/ -int tcp_txdrain(FAR struct socket *psock, - FAR const struct timespec *abstime) +int tcp_txdrain(FAR struct socket *psock, unsigned int timeout) { FAR struct tcp_conn_s *conn; sem_t waitsem; @@ -159,7 +157,7 @@ int tcp_txdrain(FAR struct socket *psock, * wait for it to drain or be be disconnected. */ - ret = net_timedwait_uninterruptible(&waitsem, abstime); + ret = net_timedwait_uninterruptible(&waitsem, timeout); /* Tear down the disconnect notifier */ diff --git a/net/tcp/tcp_wrbuffer.c b/net/tcp/tcp_wrbuffer.c index 44dcad2612..cd7c6062d7 100644 --- a/net/tcp/tcp_wrbuffer.c +++ b/net/tcp/tcp_wrbuffer.c @@ -150,7 +150,7 @@ FAR struct tcp_wrbuffer_s *tcp_wrbuffer_alloc(void) * buffer */ - while (net_lockedwait(&g_wrbuffer.sem) < 0); + net_lockedwait_uninterruptible(&g_wrbuffer.sem); /* Now, we are guaranteed to have a write buffer structure reserved * for us in the free list. diff --git a/net/udp/udp.h b/net/udp/udp.h index c2aa4ded3d..76033fd21d 100644 --- a/net/udp/udp.h +++ b/net/udp/udp.h @@ -46,7 +46,6 @@ #include #include -#include #include #include @@ -175,9 +174,6 @@ struct udp_wrbuffer_s { sq_entry_t wb_node; /* Supports a singly linked list */ struct sockaddr_storage wb_dest; /* Destination address */ -#ifdef CONFIG_NET_SOCKOPTS - clock_t wb_start; /* Start time for timeout calculation */ -#endif struct iob_s *wb_iob; /* Head of the I/O buffer chain */ }; #endif @@ -451,7 +447,6 @@ void udp_wrbuffer_initialize(void); #ifdef CONFIG_NET_UDP_WRITE_BUFFERS struct udp_wrbuffer_s; - FAR struct udp_wrbuffer_s *udp_wrbuffer_alloc(void); #endif /* CONFIG_NET_UDP_WRITE_BUFFERS */ @@ -846,7 +841,7 @@ void udp_writebuffer_signal(FAR struct udp_conn_s *conn); * * Input Parameters: * psock - An instance of the internal socket structure. - * abstime - The absolute time when the timeout will occur + * timeout - The relative time when the timeout will occur * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned @@ -855,11 +850,9 @@ void udp_writebuffer_signal(FAR struct udp_conn_s *conn); ****************************************************************************/ #if defined(CONFIG_NET_UDP_WRITE_BUFFERS) && defined(CONFIG_NET_UDP_NOTIFIER) -struct timespec; -int udp_txdrain(FAR struct socket *psock, - FAR const struct timespec *abstime); +int udp_txdrain(FAR struct socket *psock, unsigned int timeout); #else -# define udp_txdrain(conn, abstime) (0) +# define udp_txdrain(conn, timeout) (0) #endif #undef EXTERN diff --git a/net/udp/udp_psock_sendto_buffered.c b/net/udp/udp_psock_sendto_buffered.c index 047355d495..0dcf892759 100644 --- a/net/udp/udp_psock_sendto_buffered.c +++ b/net/udp/udp_psock_sendto_buffered.c @@ -61,7 +61,6 @@ #include #include -#include #include #include #include @@ -110,10 +109,6 @@ static inline void sendto_ipselect(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn); #endif -#ifdef CONFIG_NET_SOCKOPTS -static inline int sendto_timeout(FAR struct socket *psock, - FAR struct udp_conn_s *conn); -#endif static int sendto_next_transfer(FAR struct socket *psock, FAR struct udp_conn_s *conn); static uint16_t sendto_eventhandler(FAR struct net_driver_s *dev, @@ -234,52 +229,6 @@ static inline void sendto_ipselect(FAR struct net_driver_s *dev, } #endif -/**************************************************************************** - * Name: sendto_timeout - * - * Description: - * Check for send timeout. - * - * Input Parameters: - * pstate - sendto state structure - * - * Returned Value: - * TRUE:timeout FALSE:no timeout - * - * Assumptions: - * The network is locked - * - ****************************************************************************/ - -#ifdef CONFIG_NET_SOCKOPTS -static inline int sendto_timeout(FAR struct socket *psock, - FAR struct udp_conn_s *conn) -{ - FAR struct udp_wrbuffer_s *wrb; - - /* Peek at the head of the write queue (without altering the write queue). */ - - wrb = (FAR struct udp_wrbuffer_s *)sq_peek(&conn->write_q); - if (wrb != NULL) - { - /* Check for a timeout configured via setsockopts(SO_SNDTIMEO). - * If none... we well let the send wait forever. - */ - - if (psock->s_sndtimeo != 0) - { - /* Check if the configured timeout has elapsed */ - - return net_timeo(wrb->wb_start, psock->s_sndtimeo); - } - } - - /* No timeout */ - - return FALSE; -} -#endif /* CONFIG_NET_SOCKOPTS */ - /**************************************************************************** * Name: sendto_next_transfer * @@ -514,19 +463,6 @@ static uint16_t sendto_eventhandler(FAR struct net_driver_s *dev, flags &= ~UDP_POLL; } -#ifdef CONFIG_NET_SOCKOPTS - /* We cannot send the data now. Check for a timeout. */ - - else if (sendto_timeout(psock, conn)) - { - /* Free the write buffer at the head of the queue and attempt to setup - * the next transfer. - */ - - sendto_writebuffer_release(psock, conn); - } -#endif /* CONFIG_NET_SOCKOPTS */ - /* Continue waiting */ return flags; @@ -766,10 +702,6 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf, memcpy(&wrb->wb_dest, to, tolen); } -#ifdef CONFIG_NET_SOCKOPTS - wrb->wb_start = clock_systimer(); -#endif - /* Copy the user data into the write buffer. We cannot wait for * buffer space if the socket was opened non-blocking. */ diff --git a/net/udp/udp_psock_sendto_unbuffered.c b/net/udp/udp_psock_sendto_unbuffered.c index dede340975..3ced869d34 100644 --- a/net/udp/udp_psock_sendto_unbuffered.c +++ b/net/udp/udp_psock_sendto_unbuffered.c @@ -78,14 +78,11 @@ struct sendto_s { -#if defined(CONFIG_NET_SOCKOPTS) || defined(NEED_IPDOMAIN_SUPPORT) +#ifdef NEED_IPDOMAIN_SUPPORT FAR struct socket *st_sock; /* Points to the parent socket structure */ #endif FAR struct devif_callback_s *st_cb; /* Reference to callback instance */ FAR struct net_driver_s *st_dev; /* Driver that will perform the transmission */ -#ifdef CONFIG_NET_SOCKOPTS - clock_t st_time; /* Last send time for determining timeout */ -#endif sem_t st_sem; /* Semaphore signals sendto completion */ uint16_t st_buflen; /* Length of send buffer (error if <0) */ const char *st_buffer; /* Pointer to send buffer */ @@ -96,46 +93,6 @@ struct sendto_s * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: sendto_timeout - * - * Description: - * Check for send timeout. - * - * Input Parameters: - * pstate - sendto state structure - * - * Returned Value: - * TRUE:timeout FALSE:no timeout - * - * Assumptions: - * The network is locked - * - ****************************************************************************/ - -#ifdef CONFIG_NET_SOCKOPTS -static inline int sendto_timeout(FAR struct sendto_s *pstate) -{ - FAR struct socket *psock; - - /* Check for a timeout configured via setsockopts(SO_SNDTIMEO). - * If none... we well let the send wait forever. - */ - - psock = pstate->st_sock; - if (psock && psock->s_sndtimeo != 0) - { - /* Check if the configured timeout has elapsed */ - - return net_timeo(pstate->st_time, psock->s_sndtimeo); - } - - /* No timeout */ - - return FALSE; -} -#endif /* CONFIG_NET_SOCKOPTS */ - /**************************************************************************** * Name: sendto_ipselect * @@ -246,25 +203,10 @@ static uint16_t sendto_eventhandler(FAR struct net_driver_s *dev, else if (dev->d_sndlen > 0 || (flags & UDP_NEWDATA) != 0) { /* Another thread has beat us sending data or the buffer is busy, - * Check for a timeout. If not timed out, wait for the next - * polling cycle and check again. + * wait for the next polling cycle and check again. */ -#ifdef CONFIG_NET_SOCKOPTS - if (sendto_timeout(pstate)) - { - /* Yes.. report the timeout */ - - nwarn("WARNING: SEND timeout\n"); - pstate->st_sndlen = -ETIMEDOUT; - } - else -#endif /* CONFIG_NET_SOCKOPTS */ - { - /* No timeout. Just wait for the next polling cycle */ - - return flags; - } + return flags; } /* It looks like we are good to send the data */ @@ -477,7 +419,7 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf, state.st_buflen = len; state.st_buffer = buf; -#if defined(CONFIG_NET_SOCKOPTS) || defined(NEED_IPDOMAIN_SUPPORT) +#ifdef NEED_IPDOMAIN_SUPPORT /* Save the reference to the socket structure if it will be needed for * asynchronous processing. */ @@ -485,12 +427,6 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf, state.st_sock = psock; #endif -#ifdef CONFIG_NET_SOCKOPTS - /* Set the initial time for calculating timeouts */ - - state.st_time = clock_systimer(); -#endif - /* Check if the socket is connected */ if (!_SS_ISCONNECTED(psock->s_flags)) @@ -530,6 +466,7 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf, /* Set up the callback in the connection */ + ret = -ENOMEM; /* Assume allocation failure */ state.st_cb = udp_callback_alloc(state.st_dev, conn); if (state.st_cb) { @@ -542,21 +479,23 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf, netdev_txnotify_dev(state.st_dev); /* Wait for either the receive to complete or for an error/timeout to - * occur. NOTES: net_lockedwait will also terminate if a signal + * occur. NOTES: net_timedwait will also terminate if a signal * is received. */ - net_lockedwait(&state.st_sem); + ret = net_timedwait(&state.st_sem, _SO_TIMEOUT(psock->s_sndtimeo)); + if (ret >= 0) + { + /* The result of the sendto operation is the number of bytes transferred */ + + ret = state.st_sndlen; + } /* Make sure that no further events are processed */ udp_callback_free(state.st_dev, conn, state.st_cb); } - /* The result of the sendto operation is the number of bytes transferred */ - - ret = state.st_sndlen; - errout_with_lock: /* Release the semaphore */ diff --git a/net/udp/udp_setsockopt.c b/net/udp/udp_setsockopt.c index 2a68172094..8877f6192b 100644 --- a/net/udp/udp_setsockopt.c +++ b/net/udp/udp_setsockopt.c @@ -39,7 +39,6 @@ #include -#include #include #include #include @@ -47,7 +46,6 @@ #include -#include #include #include diff --git a/net/udp/udp_txdrain.c b/net/udp/udp_txdrain.c index c8b9ace05b..162935b305 100644 --- a/net/udp/udp_txdrain.c +++ b/net/udp/udp_txdrain.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include @@ -91,7 +90,7 @@ static void txdrain_worker(FAR void *arg) * * Input Parameters: * psock - An instance of the internal socket structure. - * abstime - The absolute time when the timeout will occur + * timeout - The relative time when the timeout will occur * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned @@ -99,8 +98,7 @@ static void txdrain_worker(FAR void *arg) * ****************************************************************************/ -int udp_txdrain(FAR struct socket *psock, - FAR const struct timespec *abstime) +int udp_txdrain(FAR struct socket *psock, unsigned int timeout) { FAR struct udp_conn_s *conn; sem_t waitsem; @@ -126,7 +124,7 @@ int udp_txdrain(FAR struct socket *psock, /* There is pending write data.. wait for it to drain. */ - ret = net_timedwait_uninterruptible(&waitsem, abstime); + ret = net_timedwait_uninterruptible(&waitsem, timeout); /* Tear down the notifier (in case we timed out or were canceled) */ diff --git a/net/udp/udp_wrbuffer.c b/net/udp/udp_wrbuffer.c index 9248c3afcd..3738fd5368 100644 --- a/net/udp/udp_wrbuffer.c +++ b/net/udp/udp_wrbuffer.c @@ -147,7 +147,7 @@ FAR struct udp_wrbuffer_s *udp_wrbuffer_alloc(void) * buffer */ - while (net_lockedwait(&g_wrbuffer.sem) < 0); + net_lockedwait_uninterruptible(&g_wrbuffer.sem); /* Now, we are guaranteed to have a write buffer structure reserved * for us in the free list. diff --git a/net/usrsock/usrsock_accept.c b/net/usrsock/usrsock_accept.c index edb20ede82..707ae8a3e0 100644 --- a/net/usrsock/usrsock_accept.c +++ b/net/usrsock/usrsock_accept.c @@ -240,10 +240,6 @@ int usrsock_accept(FAR struct socket *psock, FAR struct sockaddr *addr, socklen_t inaddrlen = 0; socklen_t outaddrlen = 0; int ret; -#ifdef CONFIG_NET_SOCKOPTS - struct timespec abstime; -#endif - struct timespec *ptimeo = NULL; DEBUGASSERT(conn); @@ -307,25 +303,6 @@ int usrsock_accept(FAR struct socket *psock, FAR struct sockaddr *addr, goto errout_unlock; } -#ifdef CONFIG_NET_SOCKOPTS - if (psock->s_rcvtimeo != 0) - { - DEBUGVERIFY(clock_gettime(CLOCK_REALTIME, &abstime)); - - /* Prepare timeout value for accept. */ - - abstime.tv_sec += psock->s_rcvtimeo / DSEC_PER_SEC; - abstime.tv_nsec += (psock->s_rcvtimeo % DSEC_PER_SEC) * NSEC_PER_DSEC; - if (abstime.tv_nsec >= NSEC_PER_SEC) - { - abstime.tv_sec++; - abstime.tv_nsec -= NSEC_PER_SEC; - } - - ptimeo = &abstime; - } -#endif - do { /* Check if remote end has closed connection. */ @@ -364,7 +341,8 @@ int usrsock_accept(FAR struct socket *psock, FAR struct sockaddr *addr, /* Wait for receive-avail (or abort, or timeout, or signal). */ - ret = net_timedwait(&state.reqstate.recvsem, ptimeo); + ret = net_timedwait(&state.reqstate.recvsem, + _SO_TIMEOUT(psock->s_rcvtimeo)); if (ret < 0) { if (ret == -ETIMEDOUT) diff --git a/net/usrsock/usrsock_dev.c b/net/usrsock/usrsock_dev.c index 26e9441001..a6f31badc0 100644 --- a/net/usrsock/usrsock_dev.c +++ b/net/usrsock/usrsock_dev.c @@ -961,7 +961,6 @@ static int usrsockdev_close(FAR struct file *filep) FAR struct inode *inode = filep->f_inode; FAR struct usrsockdev_s *dev; FAR struct usrsock_conn_s *conn; - struct timespec abstime; int ret; DEBUGASSERT(inode); @@ -1004,17 +1003,7 @@ static int usrsockdev_close(FAR struct file *filep) * requests. */ - DEBUGVERIFY(clock_gettime(CLOCK_REALTIME, &abstime)); - - abstime.tv_sec += 0; - abstime.tv_nsec += 10 * NSEC_PER_MSEC; - if (abstime.tv_nsec >= NSEC_PER_SEC) - { - abstime.tv_sec++; - abstime.tv_nsec -= NSEC_PER_SEC; - } - - ret = net_timedwait(&dev->req.sem, &abstime); + ret = net_timedwait(&dev->req.sem, 10); if (ret < 0) { if (ret != -ETIMEDOUT && ret != -EINTR) diff --git a/net/usrsock/usrsock_recvfrom.c b/net/usrsock/usrsock_recvfrom.c index 00f9829129..1b3e353e2e 100644 --- a/net/usrsock/usrsock_recvfrom.c +++ b/net/usrsock/usrsock_recvfrom.c @@ -227,10 +227,6 @@ ssize_t usrsock_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, socklen_t addrlen = 0; socklen_t outaddrlen = 0; ssize_t ret; -#ifdef CONFIG_NET_SOCKOPTS - struct timespec abstime; -#endif - struct timespec *ptimeo = NULL; DEBUGASSERT(conn); @@ -297,25 +293,6 @@ ssize_t usrsock_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, goto errout_unlock; } -#ifdef CONFIG_NET_SOCKOPTS - if (psock->s_rcvtimeo != 0) - { - DEBUGVERIFY(clock_gettime(CLOCK_REALTIME, &abstime)); - - /* Prepare timeout value for recvfrom. */ - - abstime.tv_sec += psock->s_rcvtimeo / DSEC_PER_SEC; - abstime.tv_nsec += (psock->s_rcvtimeo % DSEC_PER_SEC) * NSEC_PER_DSEC; - if (abstime.tv_nsec >= NSEC_PER_SEC) - { - abstime.tv_sec++; - abstime.tv_nsec -= NSEC_PER_SEC; - } - - ptimeo = &abstime; - } -#endif - do { /* Check if remote end has closed connection. */ @@ -354,7 +331,8 @@ ssize_t usrsock_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, /* Wait for receive-avail (or abort, or timeout, or signal). */ - ret = net_timedwait(&state.reqstate.recvsem, ptimeo); + ret = net_timedwait(&state.reqstate.recvsem, + _SO_TIMEOUT(psock->s_rcvtimeo)); if (ret < 0) { if (ret == -ETIMEDOUT) diff --git a/net/usrsock/usrsock_sendto.c b/net/usrsock/usrsock_sendto.c index 14c05a88d2..3906cf555f 100644 --- a/net/usrsock/usrsock_sendto.c +++ b/net/usrsock/usrsock_sendto.c @@ -219,10 +219,6 @@ ssize_t usrsock_sendto(FAR struct socket *psock, FAR const void *buf, }; ssize_t ret; -#ifdef CONFIG_NET_SOCKOPTS - struct timespec abstime; -#endif - struct timespec *ptimeo = NULL; DEBUGASSERT(conn); @@ -283,25 +279,6 @@ ssize_t usrsock_sendto(FAR struct socket *psock, FAR const void *buf, goto errout_unlock; } -#ifdef CONFIG_NET_SOCKOPTS - if (psock->s_sndtimeo != 0) - { - DEBUGVERIFY(clock_gettime(CLOCK_REALTIME, &abstime)); - - /* Prepare timeout value for sendto. */ - - abstime.tv_sec += psock->s_sndtimeo / DSEC_PER_SEC; - abstime.tv_nsec += (psock->s_sndtimeo % DSEC_PER_SEC) * NSEC_PER_DSEC; - if (abstime.tv_nsec >= NSEC_PER_SEC) - { - abstime.tv_sec++; - abstime.tv_nsec -= NSEC_PER_SEC; - } - - ptimeo = &abstime; - } -#endif - do { /* Check if remote end has closed connection. */ @@ -340,7 +317,8 @@ ssize_t usrsock_sendto(FAR struct socket *psock, FAR const void *buf, /* Wait for send-ready (or abort, or timeout, or signal). */ - ret = net_timedwait(&state.recvsem, ptimeo); + ret = net_timedwait(&state.recvsem, + _SO_TIMEOUT(psock->s_sndtimeo)); if (ret < 0) { if (ret == -ETIMEDOUT) diff --git a/net/utils/net_lock.c b/net/utils/net_lock.c index f95d408883..376bf760cb 100644 --- a/net/utils/net_lock.c +++ b/net/utils/net_lock.c @@ -44,9 +44,11 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -89,8 +91,8 @@ static int _net_takesem(void) * Name: _net_timedwait ****************************************************************************/ -static int _net_timedwait(sem_t *sem, bool interruptable, - FAR const struct timespec *abstime) +static int +_net_timedwait(sem_t *sem, bool interruptable, unsigned int timeout) { unsigned int count; irqstate_t flags; @@ -108,17 +110,29 @@ static int _net_timedwait(sem_t *sem, bool interruptable, /* Now take the semaphore, waiting if so requested. */ - if (abstime != NULL) + if (timeout != UINT_MAX) { + struct timespec abstime; + + DEBUGVERIFY(clock_gettime(CLOCK_REALTIME, &abstime)); + + abstime.tv_sec += timeout / MSEC_PER_SEC; + abstime.tv_nsec += timeout % MSEC_PER_SEC * NSEC_PER_MSEC; + if (abstime.tv_nsec >= NSEC_PER_SEC) + { + abstime.tv_sec++; + abstime.tv_nsec -= NSEC_PER_SEC; + } + /* Wait until we get the lock or until the timeout expires */ if (interruptable) { - ret = nxsem_timedwait(sem, abstime); + ret = nxsem_timedwait(sem, &abstime); } else { - ret = nxsem_timedwait_uninterruptible(sem, abstime); + ret = nxsem_timedwait_uninterruptible(sem, &abstime); } } else @@ -340,7 +354,7 @@ int net_restorelock(unsigned int count) * * Input Parameters: * sem - A reference to the semaphore to be taken. - * abstime - The absolute time to wait until a timeout is declared. + * timeout - The relative time to wait until a timeout is declared. * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned on @@ -348,9 +362,9 @@ int net_restorelock(unsigned int count) * ****************************************************************************/ -int net_timedwait(sem_t *sem, FAR const struct timespec *abstime) +int net_timedwait(sem_t *sem, unsigned int timeout) { - return _net_timedwait(sem, true, abstime); + return _net_timedwait(sem, true, timeout); } /**************************************************************************** @@ -375,7 +389,7 @@ int net_timedwait(sem_t *sem, FAR const struct timespec *abstime) int net_lockedwait(sem_t *sem) { - return net_timedwait(sem, NULL); + return net_timedwait(sem, UINT_MAX); } /**************************************************************************** @@ -387,7 +401,7 @@ int net_lockedwait(sem_t *sem) * * Input Parameters: * sem - A reference to the semaphore to be taken. - * abstime - The absolute time to wait until a timeout is declared. + * timeout - The relative time to wait until a timeout is declared. * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned on @@ -395,10 +409,9 @@ int net_lockedwait(sem_t *sem) * ****************************************************************************/ -int net_timedwait_uninterruptible(sem_t *sem, - FAR const struct timespec *abstime) +int net_timedwait_uninterruptible(sem_t *sem, unsigned int timeout) { - return _net_timedwait(sem, false, abstime); + return _net_timedwait(sem, false, timeout); } /**************************************************************************** @@ -419,7 +432,7 @@ int net_timedwait_uninterruptible(sem_t *sem, int net_lockedwait_uninterruptible(sem_t *sem) { - return net_timedwait_uninterruptible(sem, NULL); + return net_timedwait_uninterruptible(sem, UINT_MAX); } /****************************************************************************