From 5030fa81a020280c467126568027608fa08e5136 Mon Sep 17 00:00:00 2001 From: Joel Cunningham Date: Wed, 23 Nov 2016 09:45:38 -0600 Subject: [PATCH] bug #49684, api_msg: treat non-blocking ERR_MEM as ERR_WOULDBLOCK This corrects a case in lwip_netconn_do_writemore() where if a non-blocking socket receives ERR_MEM in a call to tcp_write(), it would return ERR_MEM, which would result in ENOMEM coming out of the socket layer This case can be gracefully handled by returning ERR_WOULDBLOCK since the socket is already marked as no longer writable and sent_tcp/poll_tcp will mark the socket as writable again based on available buffer space This is very similiar to how ERR_MEM is resolved for blocking sockets --- src/api/api_msg.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/api/api_msg.c b/src/api/api_msg.c index e0b062bb..10092285 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c @@ -1572,10 +1572,11 @@ err_mem: write_finished = 1; conn->current_msg->msg.w.len = 0; } - } else if ((err == ERR_MEM) && !dontblock) { - /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called - we do NOT return to the application thread, since ERR_MEM is - only a temporary error! */ + } else if (err == ERR_MEM) { + /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called. + For blocking sockets, we do NOT return to the application + thread, since ERR_MEM is only a temporary error! Non-blocking + will remain non-writable until sent_tcp/poll_tcp is called */ /* tcp_write returned ERR_MEM, try tcp_output anyway */ err_t out_err = tcp_output(conn->pcb.tcp); @@ -1586,6 +1587,11 @@ err_mem: err = out_err; write_finished = 1; conn->current_msg->msg.w.len = 0; + } else if (dontblock) { + /* non-blocking write is done on ERR_MEM */ + err = ERR_WOULDBLOCK; + write_finished = 1; + conn->current_msg->msg.w.len = 0; } } else { /* On errors != ERR_MEM, we don't try writing any more but return