Implement UDP sendto() timeouts. Currently disabled because it probably unnecessary.
This commit is contained in:
parent
fad8a2b555
commit
c9d98ea46c
@ -4639,5 +4639,7 @@
|
||||
6.28 2013-xx-xx Gregory Nutt <gnutt@nuttx.org>
|
||||
|
||||
* arch/arm/src/lpc17xx/lpc17_i2c.c: Interrupts were not being
|
||||
re-enabled in the I2C intializatin function.
|
||||
|
||||
re-enabled in the I2C intializatin function (2013-4-30).
|
||||
* net/sendto.c: Added skeleton of implementation of send timeouts
|
||||
for UDP. However, this functionality really does not make
|
||||
sense, so it is disabled in the code (2013-4-30).
|
||||
|
21
net/send.c
21
net/send.c
@ -89,7 +89,7 @@ struct send_s
|
||||
uint32_t snd_isn; /* Initial sequence number */
|
||||
uint32_t snd_acked; /* The number of bytes acked */
|
||||
#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
|
||||
uint32_t snd_time; /* last send time for determining timeout */
|
||||
uint32_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 */
|
||||
@ -118,7 +118,7 @@ struct send_s
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
|
||||
static inline int send_timeout(struct send_s *pstate)
|
||||
static inline int send_timeout(FAR struct send_s *pstate)
|
||||
{
|
||||
FAR struct socket *psock = 0;
|
||||
|
||||
@ -160,11 +160,11 @@ static inline int send_timeout(struct send_s *pstate)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t send_interrupt(struct uip_driver_s *dev, void *pvconn,
|
||||
void *pvpriv, uint16_t flags)
|
||||
static uint16_t send_interrupt(FAR struct uip_driver_s *dev, FAR void *pvconn,
|
||||
FAR void *pvpriv, uint16_t flags)
|
||||
{
|
||||
struct uip_conn *conn = (struct uip_conn*)pvconn;
|
||||
struct send_s *pstate = (struct send_s *)pvpriv;
|
||||
FAR struct uip_conn *conn = (FAR struct uip_conn*)pvconn;
|
||||
FAR struct send_s *pstate = (FAR struct send_s *)pvpriv;
|
||||
|
||||
nllvdbg("flags: %04x acked: %d sent: %d\n",
|
||||
flags, pstate->snd_acked, pstate->snd_sent);
|
||||
@ -501,7 +501,8 @@ end_wait:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
ssize_t psock_send(FAR struct socket *psock, const void *buf, size_t len, int flags)
|
||||
ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len,
|
||||
int flags)
|
||||
{
|
||||
struct send_s state;
|
||||
uip_lock_t save;
|
||||
@ -561,7 +562,7 @@ ssize_t psock_send(FAR struct socket *psock, const void *buf, size_t len, int fl
|
||||
|
||||
conn->unacked = 0;
|
||||
|
||||
/* Update the initial time for calculating timeouts */
|
||||
/* Set the initial time for calculating timeouts */
|
||||
|
||||
#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
|
||||
state.snd_time = clock_systimer();
|
||||
@ -622,7 +623,7 @@ ssize_t psock_send(FAR struct socket *psock, const void *buf, size_t len, int fl
|
||||
return state.snd_sent;
|
||||
|
||||
errout:
|
||||
*get_errno_ptr() = err;
|
||||
set_errno(err);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
@ -690,7 +691,7 @@ errout:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
ssize_t send(int sockfd, const void *buf, size_t len, int flags)
|
||||
ssize_t send(int sockfd, FAR const void *buf, size_t len, int flags)
|
||||
{
|
||||
return psock_send(sockfd_socket(sockfd), buf, len, flags);
|
||||
}
|
||||
|
111
net/sendto.c
111
net/sendto.c
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* net/sendto.c
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2011-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -47,14 +47,35 @@
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include <nuttx/clock.h>
|
||||
#include <nuttx/net/uip/uip-arch.h>
|
||||
|
||||
#include "net_internal.h"
|
||||
#include "uip/uip_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
/* timeouts on sendto() do not make sense. Each polling cycle from the
|
||||
* driver is an opportunity to send a packet. If the driver is not polling,
|
||||
* then the network is not up (and there is not polling cycles to drive
|
||||
* the timeout).
|
||||
*
|
||||
* There is a remote possibility that if there is a lot of other network
|
||||
* traffic that a UDP sendto could get delayed, but I would not expect this
|
||||
* generate a timeout.
|
||||
*/
|
||||
|
||||
#undef CONFIG_NET_SENDTO_TIMEOUT
|
||||
|
||||
/* If supported, the sendto timeout function would depend on socket options
|
||||
* and a system clock.
|
||||
*/
|
||||
|
||||
#if !defined(CONFIG_NET_SOCKOPTS) || defined(CONFIG_DISABLE_CLOCK)
|
||||
# undef CONFIG_NET_SENDTO_TIMEOUT
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
@ -62,17 +83,61 @@
|
||||
|
||||
struct sendto_s
|
||||
{
|
||||
#ifdef CONFIG_NET_SENDTO_TIMEOUT
|
||||
FAR struct socket *st_sock; /* Points to the parent socket structure */
|
||||
uint32_t st_time; /* Last send time for determining timeout */
|
||||
#endif
|
||||
FAR struct uip_callback_s *st_cb; /* Reference to callback instance */
|
||||
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 */
|
||||
int st_sndlen; /* Result of the send (length sent or negated errno) */
|
||||
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 */
|
||||
int st_sndlen; /* Result of the send (length sent or negated errno) */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Function: send_timeout
|
||||
*
|
||||
* Description:
|
||||
* Check for send timeout.
|
||||
*
|
||||
* Parameters:
|
||||
* pstate send state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* TRUE:timeout FALSE:no timeout
|
||||
*
|
||||
* Assumptions:
|
||||
* Running at the interrupt level
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_SENDTO_TIMEOUT
|
||||
static inline int send_timeout(FAR struct sendto_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->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_SENDTO_TIMEOUT */
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sendto_interrupt
|
||||
*
|
||||
@ -98,12 +163,12 @@ struct sendto_s
|
||||
static uint16_t sendto_interrupt(struct uip_driver_s *dev, void *conn,
|
||||
void *pvpriv, uint16_t flags)
|
||||
{
|
||||
struct sendto_s *pstate = (struct sendto_s *)pvpriv;
|
||||
FAR struct sendto_s *pstate = (FAR struct sendto_s *)pvpriv;
|
||||
|
||||
nllvdbg("flags: %04x\n", flags);
|
||||
if (pstate)
|
||||
{
|
||||
/* Check if the outgoing packet is available (it may have been claimed
|
||||
/* Check if the outgoing packet is available. It may have been claimed
|
||||
* by a sendto interrupt serving a different thread -OR- if the output
|
||||
* buffer currently contains unprocessed incoming data. In these cases
|
||||
* we will just have to wait for the next polling cycle.
|
||||
@ -112,10 +177,25 @@ static uint16_t sendto_interrupt(struct uip_driver_s *dev, void *conn,
|
||||
if (dev->d_sndlen > 0 || (flags & UIP_NEWDATA) != 0)
|
||||
{
|
||||
/* Another thread has beat us sending data or the buffer is busy,
|
||||
* wait for the next polling cycle
|
||||
* Check for a timeout. If not timed out, wait for the next
|
||||
* polling cycle and check again.
|
||||
*/
|
||||
|
||||
return flags;
|
||||
#ifdef CONFIG_NET_SENDTO_TIMEOUT
|
||||
if (send_timeout(pstate))
|
||||
{
|
||||
/* Yes.. report the timeout */
|
||||
|
||||
nlldbg("SEND timeout\n");
|
||||
pstate->st_sndlen = -ETIMEDOUT;
|
||||
}
|
||||
else
|
||||
#endif /* CONFIG_NET_SENDTO_TIMEOUT */
|
||||
{
|
||||
/* No timeout. Just wait for the next polling cycle */
|
||||
|
||||
return flags;
|
||||
}
|
||||
}
|
||||
|
||||
/* It looks like we are good to send the data */
|
||||
@ -283,12 +363,19 @@ ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf,
|
||||
* are ready.
|
||||
*/
|
||||
|
||||
save = uip_lock();
|
||||
save = uip_lock();
|
||||
memset(&state, 0, sizeof(struct sendto_s));
|
||||
sem_init(&state.st_sem, 0, 0);
|
||||
state.st_buflen = len;
|
||||
state.st_buffer = buf;
|
||||
|
||||
/* Set the initial time for calculating timeouts */
|
||||
|
||||
#ifdef CONFIG_NET_SENDTO_TIMEOUT
|
||||
state.st_sock = psock;
|
||||
state.st_time = clock_systimer();
|
||||
#endif
|
||||
|
||||
/* Setup the UDP socket */
|
||||
|
||||
conn = (struct uip_udp_conn *)psock->s_conn;
|
||||
@ -354,7 +441,7 @@ ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf,
|
||||
#endif
|
||||
|
||||
errout:
|
||||
errno = err;
|
||||
set_errno(err);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user