_libssh2_channel_write: don't iterate over transport writes
When a call to _libssh2_transport_write() succeeds, we must return from _libssh2_channel_write() to allow the caller to provide the next chunk of data. We cannot move on to send the next piece of data that may already have been provided in this same function call, as we risk getting EAGAIN for that and we can't return information both about sent data as well as EAGAIN. So, by returning short now, the caller will call this function again with new data to send.
Этот коммит содержится в:
родитель
4faf67d3e9
Коммит
f4d302fdfe
@ -1918,9 +1918,8 @@ _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id)
|
|||||||
/*
|
/*
|
||||||
* _libssh2_channel_write
|
* _libssh2_channel_write
|
||||||
*
|
*
|
||||||
* Send data to a channel. Note that if this returns EAGAIN or simply didn't
|
* Send data to a channel. Note that if this returns EAGAIN, the caller must
|
||||||
* send the entire packet, the caller must call this function again with the
|
* call this function again with the SAME input arguments.
|
||||||
* SAME input arguments.
|
|
||||||
*
|
*
|
||||||
* Returns: number of bytes sent, or if it returns a negative number, that is
|
* Returns: number of bytes sent, or if it returns a negative number, that is
|
||||||
* the error code!
|
* the error code!
|
||||||
@ -2034,13 +2033,6 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
|
|||||||
channel->write_s -
|
channel->write_s -
|
||||||
channel->write_packet);
|
channel->write_packet);
|
||||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||||
if(wrote) {
|
|
||||||
/* some pieces of data was sent before the EAGAIN so we
|
|
||||||
return that amount! As we ignore EAGAIN, we must drain
|
|
||||||
the outgoing transport buffer. */
|
|
||||||
_libssh2_transport_drain(session);
|
|
||||||
goto _channel_write_done;
|
|
||||||
}
|
|
||||||
return _libssh2_error(session, rc,
|
return _libssh2_error(session, rc,
|
||||||
"Unable to send channel data");
|
"Unable to send channel data");
|
||||||
}
|
}
|
||||||
@ -2054,17 +2046,20 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
|
|||||||
/* Shrink local window size */
|
/* Shrink local window size */
|
||||||
channel->local.window_size -= channel->write_bufwrite;
|
channel->local.window_size -= channel->write_bufwrite;
|
||||||
|
|
||||||
/* Adjust buf for next iteration */
|
|
||||||
buflen -= channel->write_bufwrite;
|
|
||||||
buf += channel->write_bufwrite;
|
|
||||||
channel->write_bufwrote += channel->write_bufwrite;
|
|
||||||
wrote += channel->write_bufwrite;
|
wrote += channel->write_bufwrite;
|
||||||
|
|
||||||
channel->write_state = libssh2_NB_state_allocated;
|
/* Since _libssh2_transport_write() succeeded, we must return
|
||||||
}
|
now to allow the caller to provide the next chunk of data.
|
||||||
}
|
|
||||||
|
|
||||||
_channel_write_done:
|
We cannot move on to send the next piece of data that may
|
||||||
|
already have been provided in this same function call, as we
|
||||||
|
risk getting EAGAIN for that and we can't return information
|
||||||
|
both about sent data as well as EAGAIN. So, by returning short
|
||||||
|
now, the caller will call this function again with new data to
|
||||||
|
send */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LIBSSH2_FREE(session, channel->write_packet);
|
LIBSSH2_FREE(session, channel->write_packet);
|
||||||
channel->write_packet = NULL;
|
channel->write_packet = NULL;
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user