mirror of
https://git.savannah.nongnu.org/git/lwip.git
synced 2025-08-08 23:44:39 +08:00
Implemented timeout on send (TCP only, bug #33820)
This commit is contained in:
parent
8d5514603e
commit
a2aa43a426
@ -6,6 +6,10 @@ HISTORY
|
|||||||
|
|
||||||
++ New features:
|
++ New features:
|
||||||
|
|
||||||
|
2011-09-21: Simon Goldschmidt
|
||||||
|
* opt.h, api.h, api_lib.c, api_msg.h/.c, sockets.c: Implemented timeout on
|
||||||
|
send (TCP only, bug #33820)
|
||||||
|
|
||||||
2011-09-21: Simon Goldschmidt
|
2011-09-21: Simon Goldschmidt
|
||||||
* init.c: Converted runtime-sanity-checks into compile-time checks that can
|
* init.c: Converted runtime-sanity-checks into compile-time checks that can
|
||||||
be disabled (since runtime checks can often not be seen on embedded targets)
|
be disabled (since runtime checks can often not be seen on embedded targets)
|
||||||
|
@ -611,12 +611,26 @@ netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size,
|
|||||||
msg.msg.msg.w.dataptr = dataptr;
|
msg.msg.msg.w.dataptr = dataptr;
|
||||||
msg.msg.msg.w.apiflags = apiflags;
|
msg.msg.msg.w.apiflags = apiflags;
|
||||||
msg.msg.msg.w.len = size;
|
msg.msg.msg.w.len = size;
|
||||||
|
#if LWIP_SO_SNDTIMEO
|
||||||
|
if (conn->send_timeout != 0) {
|
||||||
|
/* get the time we started, which is later compared to
|
||||||
|
sys_now() + conn->send_timeout */
|
||||||
|
msg.msg.msg.w.time_started = sys_now();
|
||||||
|
} else {
|
||||||
|
msg.msg.msg.w.time_started = 0;
|
||||||
|
}
|
||||||
|
#endif /* LWIP_SO_SNDTIMEO */
|
||||||
|
|
||||||
/* For locking the core: this _can_ be delayed on low memory/low send buffer,
|
/* For locking the core: this _can_ be delayed on low memory/low send buffer,
|
||||||
but if it is, this is done inside api_msg.c:do_write(), so we can use the
|
but if it is, this is done inside api_msg.c:do_write(), so we can use the
|
||||||
non-blocking version here. */
|
non-blocking version here. */
|
||||||
err = TCPIP_APIMSG(&msg);
|
err = TCPIP_APIMSG(&msg);
|
||||||
if ((err == ERR_OK) && (bytes_written != NULL)) {
|
if ((err == ERR_OK) && (bytes_written != NULL)) {
|
||||||
if (dontblock) {
|
if (dontblock
|
||||||
|
#if LWIP_SO_SNDTIMEO
|
||||||
|
|| (conn->send_timeout != 0)
|
||||||
|
#endif /* LWIP_SO_SNDTIMEO */
|
||||||
|
) {
|
||||||
/* nonblocking write: maybe the data has been sent partly */
|
/* nonblocking write: maybe the data has been sent partly */
|
||||||
*bytes_written = msg.msg.msg.w.len;
|
*bytes_written = msg.msg.msg.w.len;
|
||||||
} else {
|
} else {
|
||||||
|
@ -626,6 +626,9 @@ netconn_alloc(enum netconn_type t, netconn_callback callback)
|
|||||||
conn->current_msg = NULL;
|
conn->current_msg = NULL;
|
||||||
conn->write_offset = 0;
|
conn->write_offset = 0;
|
||||||
#endif /* LWIP_TCP */
|
#endif /* LWIP_TCP */
|
||||||
|
#if LWIP_SO_SNDTIMEO
|
||||||
|
conn->send_timeout = 0;
|
||||||
|
#endif /* LWIP_SO_SNDTIMEO */
|
||||||
#if LWIP_SO_RCVTIMEO
|
#if LWIP_SO_RCVTIMEO
|
||||||
conn->recv_timeout = 0;
|
conn->recv_timeout = 0;
|
||||||
#endif /* LWIP_SO_RCVTIMEO */
|
#endif /* LWIP_SO_RCVTIMEO */
|
||||||
@ -1217,6 +1220,22 @@ do_writemore(struct netconn *conn)
|
|||||||
LWIP_ASSERT("conn->write_offset < conn->current_msg->msg.w.len",
|
LWIP_ASSERT("conn->write_offset < conn->current_msg->msg.w.len",
|
||||||
conn->write_offset < conn->current_msg->msg.w.len);
|
conn->write_offset < conn->current_msg->msg.w.len);
|
||||||
|
|
||||||
|
#if LWIP_SO_SNDTIMEO
|
||||||
|
if ((conn->send_timeout != 0) &&
|
||||||
|
((s32_t)(sys_now() - conn->current_msg->msg.w.time_started) >= conn->send_timeout)) {
|
||||||
|
write_finished = 1;
|
||||||
|
if (conn->write_offset == 0) {
|
||||||
|
/* nothing has been written */
|
||||||
|
err = ERR_WOULDBLOCK;
|
||||||
|
conn->current_msg->msg.w.len = 0;
|
||||||
|
} else {
|
||||||
|
/* partial write */
|
||||||
|
err = ERR_OK;
|
||||||
|
conn->current_msg->msg.w.len = conn->write_offset;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
#endif /* LWIP_SO_SNDTIMEO */
|
||||||
|
{
|
||||||
dataptr = (u8_t*)conn->current_msg->msg.w.dataptr + conn->write_offset;
|
dataptr = (u8_t*)conn->current_msg->msg.w.dataptr + conn->write_offset;
|
||||||
diff = conn->current_msg->msg.w.len - conn->write_offset;
|
diff = conn->current_msg->msg.w.len - conn->write_offset;
|
||||||
if (diff > 0xffffUL) { /* max_u16_t */
|
if (diff > 0xffffUL) { /* max_u16_t */
|
||||||
@ -1289,7 +1308,7 @@ err_mem:
|
|||||||
write_finished = 1;
|
write_finished = 1;
|
||||||
conn->current_msg->msg.w.len = 0;
|
conn->current_msg->msg.w.len = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (write_finished) {
|
if (write_finished) {
|
||||||
/* everything was written: set back connection state
|
/* everything was written: set back connection state
|
||||||
and back to application task */
|
and back to application task */
|
||||||
|
@ -1535,7 +1535,9 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
|
|||||||
case SO_ERROR:
|
case SO_ERROR:
|
||||||
case SO_KEEPALIVE:
|
case SO_KEEPALIVE:
|
||||||
/* UNIMPL case SO_CONTIMEO: */
|
/* UNIMPL case SO_CONTIMEO: */
|
||||||
/* UNIMPL case SO_SNDTIMEO: */
|
#if LWIP_SO_SNDTIMEO
|
||||||
|
case SO_SNDTIMEO:
|
||||||
|
#endif /* LWIP_SO_SNDTIMEO */
|
||||||
#if LWIP_SO_RCVTIMEO
|
#if LWIP_SO_RCVTIMEO
|
||||||
case SO_RCVTIMEO:
|
case SO_RCVTIMEO:
|
||||||
#endif /* LWIP_SO_RCVTIMEO */
|
#endif /* LWIP_SO_RCVTIMEO */
|
||||||
@ -1780,6 +1782,11 @@ lwip_getsockopt_internal(void *arg)
|
|||||||
s, *(int *)optval));
|
s, *(int *)optval));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#if LWIP_SO_SNDTIMEO
|
||||||
|
case SO_SNDTIMEO:
|
||||||
|
*(int *)optval = netconn_get_sendtimeout(sock->conn);
|
||||||
|
break;
|
||||||
|
#endif /* LWIP_SO_SNDTIMEO */
|
||||||
#if LWIP_SO_RCVTIMEO
|
#if LWIP_SO_RCVTIMEO
|
||||||
case SO_RCVTIMEO:
|
case SO_RCVTIMEO:
|
||||||
*(int *)optval = netconn_get_recvtimeout(sock->conn);
|
*(int *)optval = netconn_get_recvtimeout(sock->conn);
|
||||||
@ -1934,7 +1941,9 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt
|
|||||||
/* UNIMPL case SO_DONTROUTE: */
|
/* UNIMPL case SO_DONTROUTE: */
|
||||||
case SO_KEEPALIVE:
|
case SO_KEEPALIVE:
|
||||||
/* UNIMPL case case SO_CONTIMEO: */
|
/* UNIMPL case case SO_CONTIMEO: */
|
||||||
/* UNIMPL case case SO_SNDTIMEO: */
|
#if LWIP_SO_SNDTIMEO
|
||||||
|
case SO_SNDTIMEO:
|
||||||
|
#endif /* LWIP_SO_SNDTIMEO */
|
||||||
#if LWIP_SO_RCVTIMEO
|
#if LWIP_SO_RCVTIMEO
|
||||||
case SO_RCVTIMEO:
|
case SO_RCVTIMEO:
|
||||||
#endif /* LWIP_SO_RCVTIMEO */
|
#endif /* LWIP_SO_RCVTIMEO */
|
||||||
@ -2160,6 +2169,11 @@ lwip_setsockopt_internal(void *arg)
|
|||||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n",
|
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n",
|
||||||
s, optname, (*(int*)optval?"on":"off")));
|
s, optname, (*(int*)optval?"on":"off")));
|
||||||
break;
|
break;
|
||||||
|
#if LWIP_SO_SNDTIMEO
|
||||||
|
case SO_SNDTIMEO:
|
||||||
|
netconn_set_sendtimeout(sock->conn, (s32_t)*(int*)optval);
|
||||||
|
break;
|
||||||
|
#endif /* LWIP_SO_SNDTIMEO */
|
||||||
#if LWIP_SO_RCVTIMEO
|
#if LWIP_SO_RCVTIMEO
|
||||||
case SO_RCVTIMEO:
|
case SO_RCVTIMEO:
|
||||||
netconn_set_recvtimeout(sock->conn, *(int*)optval);
|
netconn_set_recvtimeout(sock->conn, *(int*)optval);
|
||||||
|
@ -180,6 +180,11 @@ struct netconn {
|
|||||||
#if LWIP_SOCKET
|
#if LWIP_SOCKET
|
||||||
int socket;
|
int socket;
|
||||||
#endif /* LWIP_SOCKET */
|
#endif /* LWIP_SOCKET */
|
||||||
|
#if LWIP_SO_SNDTIMEO
|
||||||
|
/** timeout to wait for sending data (which means enqueueing data for sending
|
||||||
|
in internal buffers) */
|
||||||
|
s32_t send_timeout;
|
||||||
|
#endif /* LWIP_SO_RCVTIMEO */
|
||||||
#if LWIP_SO_RCVTIMEO
|
#if LWIP_SO_RCVTIMEO
|
||||||
/** timeout to wait for new data to be received
|
/** timeout to wait for new data to be received
|
||||||
(or connections to arrive for listening netconns) */
|
(or connections to arrive for listening netconns) */
|
||||||
@ -299,6 +304,12 @@ err_t netconn_gethostbyname(const char *name, ip_addr_t *addr);
|
|||||||
/** TCP: Get the no-auto-recved status of netconn calls (see NETCONN_FLAG_NO_AUTO_RECVED) */
|
/** TCP: Get the no-auto-recved status of netconn calls (see NETCONN_FLAG_NO_AUTO_RECVED) */
|
||||||
#define netconn_get_noautorecved(conn) (((conn)->flags & NETCONN_FLAG_NO_AUTO_RECVED) != 0)
|
#define netconn_get_noautorecved(conn) (((conn)->flags & NETCONN_FLAG_NO_AUTO_RECVED) != 0)
|
||||||
|
|
||||||
|
#if LWIP_SO_SNDTIMEO
|
||||||
|
/** Set the send timeout in milliseconds */
|
||||||
|
#define netconn_set_sendtimeout(conn, timeout) ((conn)->send_timeout = (timeout))
|
||||||
|
/** Get the send timeout in milliseconds */
|
||||||
|
#define netconn_get_sendtimeout(conn) ((conn)->send_timeout)
|
||||||
|
#endif /* LWIP_SO_SNDTIMEO */
|
||||||
#if LWIP_SO_RCVTIMEO
|
#if LWIP_SO_RCVTIMEO
|
||||||
/** Set the receive timeout in milliseconds */
|
/** Set the receive timeout in milliseconds */
|
||||||
#define netconn_set_recvtimeout(conn, timeout) ((conn)->recv_timeout = (timeout))
|
#define netconn_set_recvtimeout(conn, timeout) ((conn)->recv_timeout = (timeout))
|
||||||
|
@ -89,6 +89,9 @@ struct api_msg_msg {
|
|||||||
const void *dataptr;
|
const void *dataptr;
|
||||||
size_t len;
|
size_t len;
|
||||||
u8_t apiflags;
|
u8_t apiflags;
|
||||||
|
#if LWIP_SO_SNDTIMEO
|
||||||
|
u32_t time_started;
|
||||||
|
#endif /* LWIP_SO_SNDTIMEO */
|
||||||
} w;
|
} w;
|
||||||
/** used for do_recv */
|
/** used for do_recv */
|
||||||
struct {
|
struct {
|
||||||
|
@ -1434,6 +1434,14 @@
|
|||||||
#define LWIP_TCP_KEEPALIVE 0
|
#define LWIP_TCP_KEEPALIVE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and
|
||||||
|
* SO_SNDTIMEO processing.
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_SO_SNDTIMEO
|
||||||
|
#define LWIP_SO_SNDTIMEO 0
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and
|
* LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and
|
||||||
* SO_RCVTIMEO processing.
|
* SO_RCVTIMEO processing.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user