sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, tcp.h, tcp_out.c: Integrate "patch #6250 : MSG_MORE flag for send". MSG_MORE is used at socket api layer, NETCONN_MORE at netconn api layer, and TCP_WRITE_FLAG_MORE at raw api layer. This option enable to delayed TCP PUSH flag on multiple "write" calls. Note that previous "copy" parameter for "write" APIs is now called "apiflags".

This commit is contained in:
fbernon 2007-11-01 17:37:50 +00:00
parent 2d5908f4de
commit cbe9b050a9
9 changed files with 42 additions and 24 deletions

View File

@ -19,6 +19,13 @@ HISTORY
++ New features: ++ New features:
2007-11-01 Frédéric Bernon, Marc Chaland
* sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, tcp.h, tcp_out.c:
Integrate "patch #6250 : MSG_MORE flag for send". MSG_MORE is used at socket api
layer, NETCONN_MORE at netconn api layer, and TCP_WRITE_FLAG_MORE at raw api
layer. This option enable to delayed TCP PUSH flag on multiple "write" calls.
Note that previous "copy" parameter for "write" APIs is now called "apiflags".
2007-10-24 Frédéric Bernon 2007-10-24 Frédéric Bernon
* api.h, api_lib.c, api_msg.c: Add macro API_EVENT in the same spirit than * api.h, api_lib.c, api_msg.c: Add macro API_EVENT in the same spirit than
TCP_EVENT_xxx macros to get a code more readable. It could also help to remove TCP_EVENT_xxx macros to get a code more readable. It could also help to remove

View File

@ -546,11 +546,13 @@ netconn_send(struct netconn *conn, struct netbuf *buf)
* @param conn the TCP netconn over which to send data * @param conn the TCP netconn over which to send data
* @param dataptr pointer to the application buffer that contains the data to send * @param dataptr pointer to the application buffer that contains the data to send
* @param size size of the application data to send * @param size size of the application data to send
* @param copy flag: 1 = copy the data, 0 = data is non-volatile, can be sent by reference * @param apiflags combination of following flags :
* - NETCONN_COPY (0x01) data will be copied into memory belonging to the stack
* - NETCONN_MORE (0x02) for TCP connection, PSH flag will be set on last segment sent
* @return ERR_OK if data was sent, any other err_t on error * @return ERR_OK if data was sent, any other err_t on error
*/ */
err_t err_t
netconn_write(struct netconn *conn, const void *dataptr, int size, u8_t copy) netconn_write(struct netconn *conn, const void *dataptr, int size, u8_t apiflags)
{ {
struct api_msg msg; struct api_msg msg;
@ -560,7 +562,7 @@ netconn_write(struct netconn *conn, const void *dataptr, int size, u8_t copy)
msg.function = do_write; msg.function = do_write;
msg.msg.conn = conn; msg.msg.conn = conn;
msg.msg.msg.w.dataptr = dataptr; msg.msg.msg.w.dataptr = dataptr;
msg.msg.msg.w.copy = copy; msg.msg.msg.w.apiflags = apiflags;
msg.msg.msg.w.len = size; msg.msg.msg.w.len = size;
/* 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

View File

@ -784,7 +784,7 @@ do_writemore(struct netconn *conn)
#endif #endif
} }
err = tcp_write(conn->pcb.tcp, dataptr, len, conn->write_msg->msg.w.copy); err = tcp_write(conn->pcb.tcp, dataptr, len, conn->write_msg->msg.w.apiflags);
LWIP_ASSERT("do_writemore: invalid length!", ((conn->write_offset + len) <= conn->write_msg->msg.w.len)); LWIP_ASSERT("do_writemore: invalid length!", ((conn->write_offset + len) <= conn->write_msg->msg.w.len));
if (err == ERR_OK) { if (err == ERR_OK) {
conn->write_offset += len; conn->write_offset += len;

View File

@ -538,7 +538,7 @@ lwip_send(int s, const void *data, int size, unsigned int flags)
#endif /* (LWIP_UDP || LWIP_RAW) */ #endif /* (LWIP_UDP || LWIP_RAW) */
} }
err = netconn_write(sock->conn, data, size, NETCONN_COPY); err = netconn_write(sock->conn, data, size, NETCONN_COPY | ((flags & MSG_MORE)?NETCONN_MORE:0));
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d size=%d\n", s, err, size)); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d size=%d\n", s, err, size));
sock_set_errno(sock, err_to_errno(err)); sock_set_errno(sock, err_to_errno(err));

View File

@ -83,24 +83,25 @@ tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags)
* @param pcb Protocol control block of the TCP connection to enqueue data for. * @param pcb Protocol control block of the TCP connection to enqueue data for.
* @param data pointer to the data to send * @param data pointer to the data to send
* @param len length (in bytes) of the data to send * @param len length (in bytes) of the data to send
* @param copy 1 if data must be copied, 0 if data is non-volatile and can be * @param apiflags combination of following flags :
* referenced. * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack
* - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will be set on last segment sent,
* @return ERR_OK if enqueued, another err_t on error * @return ERR_OK if enqueued, another err_t on error
* *
* @see tcp_write() * @see tcp_write()
*/ */
err_t err_t
tcp_write(struct tcp_pcb *pcb, const void *data, u16_t len, u8_t copy) tcp_write(struct tcp_pcb *pcb, const void *data, u16_t len, u8_t apiflags)
{ {
LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, data=%p, len=%"U16_F", copy=%"U16_F")\n", (void *)pcb, LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, data=%p, len=%"U16_F", apiflags=%"U16_F")\n", (void *)pcb,
data, len, (u16_t)copy)); data, len, (u16_t)apiflags));
/* connection is in valid state for data transmission? */ /* connection is in valid state for data transmission? */
if (pcb->state == ESTABLISHED || if (pcb->state == ESTABLISHED ||
pcb->state == CLOSE_WAIT || pcb->state == CLOSE_WAIT ||
pcb->state == SYN_SENT || pcb->state == SYN_SENT ||
pcb->state == SYN_RCVD) { pcb->state == SYN_RCVD) {
if (len > 0) { if (len > 0) {
return tcp_enqueue(pcb, (void *)data, len, 0, copy, NULL, 0); return tcp_enqueue(pcb, (void *)data, len, 0, apiflags, NULL, 0);
} }
return ERR_OK; return ERR_OK;
} else { } else {
@ -118,14 +119,15 @@ tcp_write(struct tcp_pcb *pcb, const void *data, u16_t len, u8_t copy)
* @param arg Pointer to the data to be enqueued for sending. * @param arg Pointer to the data to be enqueued for sending.
* @param len Data length in bytes * @param len Data length in bytes
* @param flags tcp header flags to set in the outgoing segment * @param flags tcp header flags to set in the outgoing segment
* @param copy 1 if data must be copied, 0 if data is non-volatile and can be * @param apiflags combination of following flags :
* referenced. * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack
* - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will be set on last segment sent,
* @param optdata * @param optdata
* @param optlen * @param optlen
*/ */
err_t err_t
tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len, tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
u8_t flags, u8_t copy, u8_t flags, u8_t apiflags,
u8_t *optdata, u8_t optlen) u8_t *optdata, u8_t optlen)
{ {
struct pbuf *p; struct pbuf *p;
@ -135,8 +137,8 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
void *ptr; void *ptr;
u16_t queuelen; u16_t queuelen;
LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue(pcb=%p, arg=%p, len=%"U16_F", flags=%"X16_F", copy=%"U16_F")\n", LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue(pcb=%p, arg=%p, len=%"U16_F", flags=%"X16_F", apiflags=%"U16_F")\n",
(void *)pcb, arg, len, (u16_t)flags, (u16_t)copy)); (void *)pcb, arg, len, (u16_t)flags, (u16_t)apiflags));
LWIP_ERROR("tcp_enqueue: len == 0 || optlen == 0 (programmer violates API)", LWIP_ERROR("tcp_enqueue: len == 0 || optlen == 0 (programmer violates API)",
((len == 0) || (optlen == 0)), return ERR_ARG;); ((len == 0) || (optlen == 0)), return ERR_ARG;);
LWIP_ERROR("tcp_enqueue: arg == NULL || optdata == NULL (programmer violates API)", LWIP_ERROR("tcp_enqueue: arg == NULL || optdata == NULL (programmer violates API)",
@ -220,7 +222,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
seg->dataptr = seg->p->payload; seg->dataptr = seg->p->payload;
} }
/* copy from volatile memory? */ /* copy from volatile memory? */
else if (copy) { else if (apiflags & TCP_WRITE_FLAG_COPY) {
if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_RAM)) == NULL) { if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_RAM)) == NULL) {
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue : could not allocate memory for pbuf copy size %"U16_F"\n", seglen)); LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue : could not allocate memory for pbuf copy size %"U16_F"\n", seglen));
goto memerr; goto memerr;
@ -372,7 +374,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
/* Set the PSH flag in the last segment that we enqueued, but only /* Set the PSH flag in the last segment that we enqueued, but only
if the segment has data (indicated by seglen > 0). */ if the segment has data (indicated by seglen > 0). */
if (seg != NULL && seglen > 0 && seg->tcphdr != NULL) { if (seg != NULL && seglen > 0 && seg->tcphdr != NULL && ((apiflags & TCP_WRITE_FLAG_MORE)==0)) {
TCPH_SET_FLAG(seg->tcphdr, TCP_PSH); TCPH_SET_FLAG(seg->tcphdr, TCP_PSH);
} }

View File

@ -54,8 +54,10 @@ extern "C" {
*/ */
/* Flags for netconn_write */ /* Flags for netconn_write */
#define NETCONN_NOCOPY 0x00 #define NETCONN_NOFLAG 0x00
#define NETCONN_COPY 0x01 #define NETCONN_NOCOPY 0x00 /* Only for source code compatibility */
#define NETCONN_COPY TCP_WRITE_FLAG_COPY
#define NETCONN_MORE TCP_WRITE_FLAG_MORE
/* Helpers to process several netconn_types by the same code */ /* Helpers to process several netconn_types by the same code */
#define NETCONNTYPE_GROUP(t) (t&0xF0) #define NETCONNTYPE_GROUP(t) (t&0xF0)
@ -164,7 +166,7 @@ err_t netconn_send (struct netconn *conn,
struct netbuf *buf); struct netbuf *buf);
err_t netconn_write (struct netconn *conn, err_t netconn_write (struct netconn *conn,
const void *dataptr, int size, const void *dataptr, int size,
u8_t copy); u8_t apiflags);
err_t netconn_close (struct netconn *conn); err_t netconn_close (struct netconn *conn);
#if LWIP_IGMP #if LWIP_IGMP

View File

@ -64,7 +64,7 @@ struct api_msg_msg {
struct { struct {
const void *dataptr; const void *dataptr;
int len; int len;
u8_t copy; u8_t apiflags;
} w; /* do_write */ } w; /* do_write */
struct { struct {
u16_t len; u16_t len;

View File

@ -132,6 +132,7 @@ struct linger {
#define MSG_WAITALL 0x02 /* Requests that the function block until the full amount of data requested can be returned */ #define MSG_WAITALL 0x02 /* Requests that the function block until the full amount of data requested can be returned */
#define MSG_OOB 0x04 /* Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */ #define MSG_OOB 0x04 /* Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */
#define MSG_DONTWAIT 0x08 /* Nonblocking i/o for this operation only */ #define MSG_DONTWAIT 0x08 /* Nonblocking i/o for this operation only */
#define MSG_MORE 0x10 /* Sender will send more */
/* /*

View File

@ -89,8 +89,12 @@ err_t tcp_connect (struct tcp_pcb *pcb, struct ip_addr *ipaddr,
struct tcp_pcb * tcp_listen (struct tcp_pcb *pcb); struct tcp_pcb * tcp_listen (struct tcp_pcb *pcb);
void tcp_abort (struct tcp_pcb *pcb); void tcp_abort (struct tcp_pcb *pcb);
err_t tcp_close (struct tcp_pcb *pcb); err_t tcp_close (struct tcp_pcb *pcb);
#define TCP_WRITE_FLAG_COPY 0x01
#define TCP_WRITE_FLAG_MORE 0x02
err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len, err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len,
u8_t copy); u8_t apiflags);
void tcp_setprio (struct tcp_pcb *pcb, u8_t prio); void tcp_setprio (struct tcp_pcb *pcb, u8_t prio);
@ -483,7 +487,7 @@ struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg);
err_t tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags); err_t tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags);
err_t tcp_enqueue(struct tcp_pcb *pcb, void *dataptr, u16_t len, err_t tcp_enqueue(struct tcp_pcb *pcb, void *dataptr, u16_t len,
u8_t flags, u8_t copy, u8_t flags, u8_t apiflags,
u8_t *optdata, u8_t optlen); u8_t *optdata, u8_t optlen);
void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg); void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg);