_libssh2_channel_write: general code cleanup

simplified the function and removed some unused struct fields
This commit is contained in:
Daniel Stenberg
2010-10-23 00:35:10 +02:00
parent c48840ba88
commit 030b2d9b60
2 changed files with 80 additions and 91 deletions

View File

@@ -1994,8 +1994,6 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
buflen = 32700;
if (channel->write_state == libssh2_NB_state_idle) {
channel->write_bufwrote = 0;
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Writing %d bytes on channel %lu/%lu, stream #%d",
(int) buflen, channel->local.id, channel->remote.id,
@@ -2012,104 +2010,97 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
"data might be ignored");
}
/* [13] 9 = packet_type(1) + channelno(4) [ + streamid(4) ] +
buflen(4) */
channel->write_packet_len = (stream_id ? 13 : 9);
channel->write_state = libssh2_NB_state_allocated;
}
/* Deduct the amount that has already been sent, and set buf accordingly. */
buflen -= channel->write_bufwrote;
buf += channel->write_bufwrote;
while (buflen > 0) {
if (channel->write_state == libssh2_NB_state_allocated) {
if (channel->write_state == libssh2_NB_state_allocated) {
unsigned char *s = channel->write_packet;
/* drain the incoming flow first */
do
rc = _libssh2_transport_read(session);
while (rc > 0);
/* drain the incoming flow first */
do
rc = _libssh2_transport_read(session);
while (rc > 0);
if(channel->local.window_size <= 0) {
/* there's no more room for data so we stop sending now */
break;
}
if(channel->local.window_size <= 0) {
/* there's no room for data so we stop */
channel->write_state = libssh2_NB_state_idle;
return 0;
}
channel->write_bufwrite = buflen;
channel->write_s = channel->write_packet;
channel->write_bufwrite = buflen;
*(channel->write_s++) =
stream_id ? SSH_MSG_CHANNEL_EXTENDED_DATA :
SSH_MSG_CHANNEL_DATA;
_libssh2_store_u32(&channel->write_s, channel->remote.id);
if (stream_id)
_libssh2_store_u32(&channel->write_s, stream_id);
/* Don't exceed the remote end's limits */
/* REMEMBER local means local as the SOURCE of the data */
if (channel->write_bufwrite > channel->local.window_size) {
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Splitting write block due to %lu byte "
"window_size on %lu/%lu/%d",
channel->local.window_size, channel->local.id,
channel->remote.id, stream_id);
channel->write_bufwrite = channel->local.window_size;
}
if (channel->write_bufwrite > channel->local.packet_size) {
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Splitting write block due to %lu byte "
"packet_size on %lu/%lu/%d",
channel->local.packet_size, channel->local.id,
channel->remote.id, stream_id);
channel->write_bufwrite = channel->local.packet_size;
}
/* store the size here only, the buffer is passed in as-is to
_libssh2_transport_send() */
_libssh2_store_u32(&channel->write_s, channel->write_bufwrite);
*(s++) = stream_id ? SSH_MSG_CHANNEL_EXTENDED_DATA :
SSH_MSG_CHANNEL_DATA;
_libssh2_store_u32(&s, channel->remote.id);
if (stream_id)
_libssh2_store_u32(&s, stream_id);
/* Don't exceed the remote end's limits */
/* REMEMBER local means local as the SOURCE of the data */
if (channel->write_bufwrite > channel->local.window_size) {
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Sending %d bytes on channel %lu/%lu, stream_id=%d",
(int) channel->write_bufwrite, channel->local.id,
"Splitting write block due to %lu byte "
"window_size on %lu/%lu/%d",
channel->local.window_size, channel->local.id,
channel->remote.id, stream_id);
channel->write_state = libssh2_NB_state_created;
channel->write_bufwrite = channel->local.window_size;
}
if (channel->write_state == libssh2_NB_state_created) {
rc = _libssh2_transport_send(session, channel->write_packet,
channel->write_s -
channel->write_packet,
buf, channel->write_bufwrite);
if (rc == LIBSSH2_ERROR_EAGAIN) {
return _libssh2_error(session, rc,
"Unable to send channel data");
}
else if (rc) {
channel->write_state = libssh2_NB_state_idle;
return _libssh2_error(session, rc,
"Unable to send channel data");
}
/* Shrink local window size */
channel->local.window_size -= channel->write_bufwrite;
wrote += channel->write_bufwrite;
/* Since _libssh2_transport_write() succeeded, we must return
now 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 */
break;
if (channel->write_bufwrite > channel->local.packet_size) {
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Splitting write block due to %lu byte "
"packet_size on %lu/%lu/%d",
channel->local.packet_size, channel->local.id,
channel->remote.id, stream_id);
channel->write_bufwrite = channel->local.packet_size;
}
/* store the size here only, the buffer is passed in as-is to
_libssh2_transport_send() */
_libssh2_store_u32(&s, channel->write_bufwrite);
channel->write_packet_len = s - channel->write_packet;
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Sending %d bytes on channel %lu/%lu, stream_id=%d",
(int) channel->write_bufwrite, channel->local.id,
channel->remote.id, stream_id);
channel->write_state = libssh2_NB_state_created;
}
channel->write_state = libssh2_NB_state_idle;
if (channel->write_state == libssh2_NB_state_created) {
rc = _libssh2_transport_send(session, channel->write_packet,
channel->write_packet_len,
buf, channel->write_bufwrite);
if (rc == LIBSSH2_ERROR_EAGAIN) {
return _libssh2_error(session, rc,
"Unable to send channel data");
}
else if (rc) {
channel->write_state = libssh2_NB_state_idle;
return _libssh2_error(session, rc,
"Unable to send channel data");
}
/* Shrink local window size */
channel->local.window_size -= channel->write_bufwrite;
return wrote;
wrote += channel->write_bufwrite;
/* Since _libssh2_transport_write() succeeded, we must return
now 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 */
channel->write_state = libssh2_NB_state_idle;
return wrote;
}
return LIBSSH2_ERROR_INVAL; /* reaching this point is really bad */
}
/*

View File

@@ -398,9 +398,7 @@ struct _LIBSSH2_CHANNEL
/* State variables used in libssh2_channel_write_ex() */
libssh2_nonblocking_states write_state;
unsigned char write_packet[13];
unsigned char *write_s;
size_t write_packet_len;
size_t write_bufwrote;
size_t write_bufwrite;
/* State variables used in libssh2_channel_close() */