1
1

libssh2_channel_read_ex() needed more changes to fully support

non-blocking IO
Этот коммит содержится в:
James Housley 2007-06-18 22:39:30 +00:00
родитель 9dfd71121e
Коммит 7808cab1e4
2 изменённых файлов: 18 добавлений и 14 удалений

Просмотреть файл

@ -1184,7 +1184,7 @@ LIBSSH2_API ssize_t
libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size_t buflen) libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size_t buflen)
{ {
LIBSSH2_SESSION *session = channel->session; LIBSSH2_SESSION *session = channel->session;
libssh2pack_t rc=0; libssh2pack_t rc = 0;
if (channel->read_state == libssh2_NB_state_idle) { if (channel->read_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Attempting to read %d bytes from channel %lu/%lu stream #%d", _libssh2_debug(session, LIBSSH2_DBG_CONN, "Attempting to read %d bytes from channel %lu/%lu stream #%d",
@ -1207,8 +1207,6 @@ libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size
channel->read_bytes_read = 0; channel->read_bytes_read = 0;
channel->read_block = 0; channel->read_block = 0;
rc = 0;
channel->read_packet = session->packets.head; channel->read_packet = session->packets.head;
channel->read_state = libssh2_NB_state_created; channel->read_state = libssh2_NB_state_created;
@ -1223,6 +1221,8 @@ libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size
goto channel_read_ex_point1; goto channel_read_ex_point1;
} }
rc = 0;
do { do {
if (channel->read_block) { if (channel->read_block) {
/* in the second lap and onwards, do this */ /* in the second lap and onwards, do this */
@ -1262,21 +1262,22 @@ libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size
(channel->local.id == channel->read_local_id) && (channel->local.id == channel->read_local_id) &&
(channel->remote.extended_data_ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) { (channel->remote.extended_data_ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) {
int want = buflen - channel->read_bytes_read; channel->read_want = buflen - channel->read_bytes_read;
int unlink_packet = 0; channel->read_unlink_packet = 0;
if (want >= (int)(channel->read_packet->data_len - channel->read_packet->data_head)) { if (channel->read_want >= (int)(channel->read_packet->data_len - channel->read_packet->data_head)) {
want = channel->read_packet->data_len - channel->read_packet->data_head; channel->read_want = channel->read_packet->data_len - channel->read_packet->data_head;
unlink_packet = 1; channel->read_unlink_packet = 1;
} }
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Reading %d of buffered data from %lu/%lu/%d", _libssh2_debug(session, LIBSSH2_DBG_CONN, "Reading %d of buffered data from %lu/%lu/%d",
want, channel->local.id, channel->remote.id, stream_id); channel->read_want, channel->local.id, channel->remote.id, stream_id);
memcpy(buf + channel->read_bytes_read, channel->read_packet->data + channel->read_packet->data_head, want); memcpy(buf + channel->read_bytes_read, channel->read_packet->data + channel->read_packet->data_head,
channel->read_packet->data_head += want; channel->read_want);
channel->read_bytes_read += want; channel->read_packet->data_head += channel->read_want;
channel->read_bytes_read += channel->read_want;
if (unlink_packet) { if (channel->read_unlink_packet) {
if (channel->read_packet->prev) { if (channel->read_packet->prev) {
channel->read_packet->prev->next = channel->read_packet->next; channel->read_packet->prev->next = channel->read_packet->next;
} else { } else {
@ -1306,8 +1307,9 @@ channel_read_ex_point1:
channel->read_packet = channel->read_next; channel->read_packet = channel->read_next;
} }
channel->read_block = 1; channel->read_block = 1;
} while (channel->session->socket_block && (channel->read_bytes_read == 0) && !channel->remote.close); } while ((channel->read_bytes_read == 0) && !channel->remote.close);
channel->read_state = libssh2_NB_state_idle;
if (channel->read_bytes_read == 0) { if (channel->read_bytes_read == 0) {
if (channel->session->socket_block) { if (channel->session->socket_block) {
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_CLOSED, "Remote end has closed this channel", 0); libssh2_error(session, LIBSSH2_ERROR_CHANNEL_CLOSED, "Remote end has closed this channel", 0);

Просмотреть файл

@ -327,6 +327,8 @@ struct _LIBSSH2_CHANNEL {
int read_block; int read_block;
int read_bytes_read; int read_bytes_read;
uint32_t read_local_id; uint32_t read_local_id;
int read_want;
int read_unlink_packet;
/* State variables used in libssh2_channel_write_ex() */ /* State variables used in libssh2_channel_write_ex() */
libssh2_nonblocking_states write_state; libssh2_nonblocking_states write_state;