do_writemore: fix blocking bug

A bug was introduced in the atomic vector feature for blocking netconns
where if we couldn't write the entire vector due to send buffer being
full (write_more is 0), we would not update the vector state and then
when sent_tcp() is called, it would actually re-send the previous vector
and if additional calls were required to finish the write, msg.w.offset
would eventually exceed msg.w.len, This was found by testing "stats"
from the shell and hitting the LWIP_ASSERT in do_writemore() that
checks offset < len

The fix simply updates the vector state after every ERR_OK return from
tcp_write().  While not all cases (non-blocking sockets) need to update
the state in this case, it keeps the logic simple and also makes
debugging simpler because you don't have stale vector state at any
point
This commit is contained in:
Joel Cunningham 2017-03-04 12:29:43 -06:00
parent 02be2f8f42
commit dd4ded3978

View File

@ -1560,17 +1560,14 @@ lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM)
err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags);
if (err == ERR_OK) {
conn->current_msg->msg.w.offset += len;
/* update write state if making another loop */
if (write_more) {
conn->current_msg->msg.w.vector_off += len;
/* check if current vector is finished */
if (conn->current_msg->msg.w.vector_off == conn->current_msg->msg.w.vector->len) {
conn->current_msg->msg.w.vector_cnt--;
/* if we have additional vectors, move on to them */
if (conn->current_msg->msg.w.vector_cnt > 0) {
conn->current_msg->msg.w.vector++;
conn->current_msg->msg.w.vector_off = 0;
}
conn->current_msg->msg.w.vector_off += len;
/* check if current vector is finished */
if (conn->current_msg->msg.w.vector_off == conn->current_msg->msg.w.vector->len) {
conn->current_msg->msg.w.vector_cnt--;
/* if we have additional vectors, move on to them */
if (conn->current_msg->msg.w.vector_cnt > 0) {
conn->current_msg->msg.w.vector++;
conn->current_msg->msg.w.vector_off = 0;
}
}
}