From 29e65c28224e0e0db2aff535b9eea92cf5a5eccd Mon Sep 17 00:00:00 2001 From: John-Mark Gurney Date: Wed, 6 Jan 2021 00:55:34 +0000 Subject: [PATCH] when in non-blocking mode, return _EAGAIN.. There is no way the consumer knows that another write is outstanding.. This is safe as it will "never" block, as soon as there is space, select will return, and the correct write should be called to finish itself up, unblocking the other... I can picture a deadlock though where the write flag gets cleared when finished up, and the other channel write was previously _EAGAIN'd... This implies that a similar solution to read needs to be done, which is if any write happens, spin the loop again, trying all the outstanding writes to make sure they get a chance.. --- libssh2/src/transport.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libssh2/src/transport.c b/libssh2/src/transport.c index dbee285..7bb62d8 100644 --- a/libssh2/src/transport.c +++ b/libssh2/src/transport.c @@ -641,7 +641,12 @@ send_existing(LIBSSH2_SESSION *session, const unsigned char *data, we don't add this one up until the previous one has been sent. To make the caller really notice his/hers flaw, we return error for this case */ - return LIBSSH2_ERROR_BAD_USE; + /* In the non-blocking mode, another channel is waiting, so return + _EAGAIN, so the other channel can finish writing. */ + if (session->api_block_mode) + return LIBSSH2_ERROR_BAD_USE; + else + return LIBSSH2_ERROR_EAGAIN; } *ret = 1; /* set to make our parent return */