You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by sh...@apache.org on 2016/05/27 16:22:55 UTC
[trafficserver] branch master updated: TS-4309: Simplify read/write
loops to address upload/download speed problems. This closes #629.
This is an automated email from the ASF dual-hosted git repository.
shinrich pushed a commit to branch master
in repository https://git-dual.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new a647412 TS-4309: Simplify read/write loops to address upload/download speed problems. This closes #629.
a647412 is described below
commit a647412f20f3a8858c3fa4fc1cc4e9c623b68e92
Author: Susan Hinrichs <sh...@ieee.org>
AuthorDate: Wed May 11 23:29:02 2016 +0000
TS-4309: Simplify read/write loops to address upload/download speed problems. This closes #629.
---
iocore/net/P_SSLNetVConnection.h | 3 +-
iocore/net/P_UnixNetVConnection.h | 3 +-
iocore/net/SSLNetVConnection.cc | 261 +++++++++++++++++---------------------
iocore/net/UnixNetVConnection.cc | 70 ++++------
4 files changed, 146 insertions(+), 191 deletions(-)
diff --git a/iocore/net/P_SSLNetVConnection.h b/iocore/net/P_SSLNetVConnection.h
index a4ae8b3..005e581 100644
--- a/iocore/net/P_SSLNetVConnection.h
+++ b/iocore/net/P_SSLNetVConnection.h
@@ -120,8 +120,7 @@ public:
int sslServerHandShakeEvent(int &err);
int sslClientHandShakeEvent(int &err);
virtual void net_read_io(NetHandler *nh, EThread *lthread);
- virtual int64_t load_buffer_and_write(int64_t towrite, int64_t &wattempted, int64_t &total_written, MIOBufferAccessor &buf,
- int &needs);
+ virtual int64_t load_buffer_and_write(int64_t towrite, MIOBufferAccessor &buf, int64_t &total_written, int &needs);
void registerNextProtocolSet(const SSLNextProtocolSet *);
virtual void do_io_close(int lerrno = -1);
diff --git a/iocore/net/P_UnixNetVConnection.h b/iocore/net/P_UnixNetVConnection.h
index 14786eb..d09ba49 100644
--- a/iocore/net/P_UnixNetVConnection.h
+++ b/iocore/net/P_UnixNetVConnection.h
@@ -208,8 +208,7 @@ public:
(void)state;
}
virtual void net_read_io(NetHandler *nh, EThread *lthread);
- virtual int64_t load_buffer_and_write(int64_t towrite, int64_t &wattempted, int64_t &total_written, MIOBufferAccessor &buf,
- int &needs);
+ virtual int64_t load_buffer_and_write(int64_t towrite, MIOBufferAccessor &buf, int64_t &total_written, int &needs);
void readDisable(NetHandler *nh);
void readSignalError(NetHandler *nh, int err);
int readSignalDone(int event, NetHandler *nh);
diff --git a/iocore/net/SSLNetVConnection.cc b/iocore/net/SSLNetVConnection.cc
index 27dc985..c6e0e5a 100644
--- a/iocore/net/SSLNetVConnection.cc
+++ b/iocore/net/SSLNetVConnection.cc
@@ -193,131 +193,121 @@ ssl_read_from_net(SSLNetVConnection *sslvc, EThread *lthread, int64_t &ret)
{
NetState *s = &sslvc->read;
MIOBufferAccessor &buf = s->vio.buffer;
- IOBufferBlock *b = buf.writer()->first_write_block();
int event = SSL_READ_ERROR_NONE;
int64_t bytes_read = 0;
- int64_t block_write_avail = 0;
ssl_error_t sslErr = SSL_ERROR_NONE;
int64_t nread = 0;
bool trace = sslvc->getSSLTrace();
Debug("ssl", "trace=%s", trace ? "TRUE" : "FALSE");
- for (bytes_read = 0; (b != 0) && (sslErr == SSL_ERROR_NONE); b = b->next.get()) {
- block_write_avail = b->write_avail();
+ bytes_read = 0;
+ while (sslErr == SSL_ERROR_NONE) {
+ int64_t block_write_avail = buf.writer()->block_write_avail();
+ if (block_write_avail <= 0) {
+ buf.writer()->add_block();
+ block_write_avail = buf.writer()->block_write_avail();
+ if (block_write_avail <= 0) {
+ Warning("Cannot add new block");
+ break;
+ }
+ }
Debug("ssl", "[SSL_NetVConnection::ssl_read_from_net] b->write_avail()=%" PRId64, block_write_avail);
+ char *current_block = buf.writer()->end();
+ sslErr = SSLReadBuffer(sslvc->ssl, current_block, block_write_avail, nread);
- int64_t offset = 0;
- // while can be replaced with if - need to test what works faster with openssl
- while (block_write_avail > 0) {
- sslErr = SSLReadBuffer(sslvc->ssl, b->end() + offset, block_write_avail, nread);
-
- Debug("ssl", "[SSL_NetVConnection::ssl_read_from_net] nread=%d", (int)nread);
- if (!sslvc->origin_trace) {
- TraceIn((0 < nread && trace), sslvc->get_remote_addr(), sslvc->get_remote_port(), "WIRE TRACE\tbytes=%d\n%.*s", (int)nread,
- (int)nread, b->end() + offset);
- } else {
- char origin_trace_ip[INET6_ADDRSTRLEN];
- ats_ip_ntop(sslvc->origin_trace_addr, origin_trace_ip, sizeof(origin_trace_ip));
- TraceIn((0 < nread && trace), sslvc->get_remote_addr(), sslvc->get_remote_port(), "CLIENT %s:%d\ttbytes=%d\n%.*s",
- origin_trace_ip, sslvc->origin_trace_port, (int)nread, (int)nread, b->end() + offset);
- }
+ Debug("ssl", "[SSL_NetVConnection::ssl_read_from_net] nread=%d", (int)nread);
+ if (!sslvc->origin_trace) {
+ TraceIn((0 < nread && trace), sslvc->get_remote_addr(), sslvc->get_remote_port(), "WIRE TRACE\tbytes=%d\n%.*s", (int)nread,
+ (int)nread, current_block);
+ } else {
+ char origin_trace_ip[INET6_ADDRSTRLEN];
+ ats_ip_ntop(sslvc->origin_trace_addr, origin_trace_ip, sizeof(origin_trace_ip));
+ TraceIn((0 < nread && trace), sslvc->get_remote_addr(), sslvc->get_remote_port(), "CLIENT %s:%d\ttbytes=%d\n%.*s",
+ origin_trace_ip, sslvc->origin_trace_port, (int)nread, (int)nread, current_block);
+ }
- switch (sslErr) {
- case SSL_ERROR_NONE:
+ switch (sslErr) {
+ case SSL_ERROR_NONE:
#if DEBUG
- SSLDebugBufferPrint("ssl_buff", b->end() + offset, nread, "SSL Read");
+ SSLDebugBufferPrint("ssl_buff", current_block, nread, "SSL Read");
#endif
-
- ink_assert(nread);
-
- bytes_read += nread;
- offset += nread;
- block_write_avail -= nread;
- ink_assert(block_write_avail >= 0);
-
- continue;
-
- case SSL_ERROR_WANT_WRITE:
- event = SSL_WRITE_WOULD_BLOCK;
- SSL_INCREMENT_DYN_STAT(ssl_error_want_write);
- Debug("ssl.error", "[SSL_NetVConnection::ssl_read_from_net] SSL_ERROR_WOULD_BLOCK(write)");
- break;
- case SSL_ERROR_WANT_READ:
- event = SSL_READ_WOULD_BLOCK;
- SSL_INCREMENT_DYN_STAT(ssl_error_want_read);
- Debug("ssl.error", "[SSL_NetVConnection::ssl_read_from_net] SSL_ERROR_WOULD_BLOCK(read)");
- break;
- case SSL_ERROR_WANT_X509_LOOKUP:
- TraceIn(trace, sslvc->get_remote_addr(), sslvc->get_remote_port(), "Want X509 lookup");
- event = SSL_READ_WOULD_BLOCK;
- SSL_INCREMENT_DYN_STAT(ssl_error_want_x509_lookup);
- Debug("ssl.error", "[SSL_NetVConnection::ssl_read_from_net] SSL_ERROR_WOULD_BLOCK(read/x509 lookup)");
- break;
- case SSL_ERROR_SYSCALL:
- TraceIn(trace, sslvc->get_remote_addr(), sslvc->get_remote_port(), "Syscall Error: %s", strerror(errno));
- SSL_INCREMENT_DYN_STAT(ssl_error_syscall);
- if (nread != 0) {
- // not EOF
- event = SSL_READ_ERROR;
- ret = errno;
- Debug("ssl.error", "[SSL_NetVConnection::ssl_read_from_net] SSL_ERROR_SYSCALL, underlying IO error: %s", strerror(errno));
- TraceIn(trace, sslvc->get_remote_addr(), sslvc->get_remote_port(), "Underlying IO error: %d", errno);
- } else {
- // then EOF observed, treat it as EOS
- event = SSL_READ_EOS;
- Debug("ssl.error", "[SSL_NetVConnection::ssl_read_from_net] SSL_ERROR_SYSCALL, EOF observed violating SSL protocol");
- TraceIn(trace, sslvc->get_remote_addr(), sslvc->get_remote_port(), "EOF observed violating SSL protocol");
- }
- break;
- case SSL_ERROR_ZERO_RETURN:
- TraceIn(trace, sslvc->get_remote_addr(), sslvc->get_remote_port(), "Connection closed by peer");
- event = SSL_READ_EOS;
- SSL_INCREMENT_DYN_STAT(ssl_error_zero_return);
- Debug("ssl.error", "[SSL_NetVConnection::ssl_read_from_net] SSL_ERROR_ZERO_RETURN");
- break;
- case SSL_ERROR_SSL:
- default: {
- Debug("ssl.error", "[SSL_NetVConnection::ssl_read_from_net] SSL_ERROR_SSL and default case");
- char buf[512];
- unsigned long e = ERR_peek_last_error();
- ERR_error_string_n(e, buf, sizeof(buf));
- TraceIn(trace, sslvc->get_remote_addr(), sslvc->get_remote_port(), "SSL Error: sslErr=%d, ERR_get_error=%ld (%s) errno=%d",
- sslErr, e, buf, errno);
+ ink_assert(nread);
+ bytes_read += nread;
+ if (nread > 0) {
+ buf.writer()->fill(nread); // Tell the buffer, we've used the bytes
+ }
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ event = SSL_WRITE_WOULD_BLOCK;
+ SSL_INCREMENT_DYN_STAT(ssl_error_want_write);
+ Debug("ssl.error", "[SSL_NetVConnection::ssl_read_from_net] SSL_ERROR_WOULD_BLOCK(write)");
+ break;
+ case SSL_ERROR_WANT_READ:
+ event = SSL_READ_WOULD_BLOCK;
+ SSL_INCREMENT_DYN_STAT(ssl_error_want_read);
+ Debug("ssl.error", "[SSL_NetVConnection::ssl_read_from_net] SSL_ERROR_WOULD_BLOCK(read)");
+ break;
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ TraceIn(trace, sslvc->get_remote_addr(), sslvc->get_remote_port(), "Want X509 lookup");
+ event = SSL_READ_WOULD_BLOCK;
+ SSL_INCREMENT_DYN_STAT(ssl_error_want_x509_lookup);
+ Debug("ssl.error", "[SSL_NetVConnection::ssl_read_from_net] SSL_ERROR_WOULD_BLOCK(read/x509 lookup)");
+ break;
+ case SSL_ERROR_SYSCALL:
+ TraceIn(trace, sslvc->get_remote_addr(), sslvc->get_remote_port(), "Syscall Error: %s", strerror(errno));
+ SSL_INCREMENT_DYN_STAT(ssl_error_syscall);
+ if (nread != 0) {
+ // not EOF
event = SSL_READ_ERROR;
ret = errno;
- SSL_CLR_ERR_INCR_DYN_STAT(sslvc, ssl_error_ssl, "[SSL_NetVConnection::ssl_read_from_net]: errno=%d", errno);
- } break;
- } // switch
+ Debug("ssl.error", "[SSL_NetVConnection::ssl_read_from_net] SSL_ERROR_SYSCALL, underlying IO error: %s", strerror(errno));
+ TraceIn(trace, sslvc->get_remote_addr(), sslvc->get_remote_port(), "Underlying IO error: %d", errno);
+ } else {
+ // then EOF observed, treat it as EOS
+ // Error("[SSL_NetVConnection::ssl_read_from_net] SSL_ERROR_SYSCALL, EOF observed violating SSL protocol");
+ TraceIn(trace, sslvc->get_remote_addr(), sslvc->get_remote_port(), "EOF observed violating SSL protocol");
+ }
+ break;
+ case SSL_ERROR_ZERO_RETURN:
+ TraceIn(trace, sslvc->get_remote_addr(), sslvc->get_remote_port(), "Connection closed by peer");
+ event = SSL_READ_EOS;
+ SSL_INCREMENT_DYN_STAT(ssl_error_zero_return);
+ Debug("ssl.error", "[SSL_NetVConnection::ssl_read_from_net] SSL_ERROR_ZERO_RETURN");
break;
- } // while( block_write_avail > 0 )
- } // for ( bytes_read = 0; (b != 0); b = b->next)
+ case SSL_ERROR_SSL:
+ default: {
+ char buf[512];
+ unsigned long e = ERR_peek_last_error();
+ ERR_error_string_n(e, buf, sizeof(buf));
+ TraceIn(trace, sslvc->get_remote_addr(), sslvc->get_remote_port(), "SSL Error: sslErr=%d, ERR_get_error=%ld (%s) errno=%d",
+ sslErr, e, buf, errno);
+ event = SSL_READ_ERROR;
+ ret = errno;
+ SSL_CLR_ERR_INCR_DYN_STAT(sslvc, ssl_error_ssl, "[SSL_NetVConnection::ssl_read_from_net]: errno=%d", errno);
+ } break;
+ } // switch
+ } // while
if (bytes_read > 0) {
Debug("ssl", "[SSL_NetVConnection::ssl_read_from_net] bytes_read=%" PRId64, bytes_read);
- buf.writer()->fill(bytes_read);
s->vio.ndone += bytes_read;
sslvc->netActivity(lthread);
ret = bytes_read;
- if (s->vio.ntodo() <= 0) {
- event = SSL_READ_COMPLETE;
- } else {
- event = SSL_READ_READY;
- }
- } else // if( bytes_read > 0 )
- {
+ event = (s->vio.ntodo() <= 0) ? SSL_READ_COMPLETE : SSL_READ_READY;
+ } else { // if( bytes_read > 0 )
#if defined(_DEBUG)
if (bytes_read == 0) {
Debug("ssl", "[SSL_NetVConnection::ssl_read_from_net] bytes_read == 0");
}
#endif
}
- return (event);
+ return event;
}
/**
@@ -647,17 +637,14 @@ SSLNetVConnection::net_read_io(NetHandler *nh, EThread *lthread)
}
int64_t
-SSLNetVConnection::load_buffer_and_write(int64_t towrite, int64_t &wattempted, int64_t &total_written, MIOBufferAccessor &buf,
- int &needs)
+SSLNetVConnection::load_buffer_and_write(int64_t towrite, MIOBufferAccessor &buf, int64_t &total_written, int &needs)
{
- int64_t r = 0;
+ int64_t try_to_write;
+ int64_t num_really_written = 0;
int64_t l = 0;
uint32_t dynamic_tls_record_size = 0;
ssl_error_t err = SSL_ERROR_NONE;
-
- // XXX Rather than dealing with the block directly, we should use the IOBufferReader API.
- int64_t offset = buf.reader()->start_offset;
- IOBufferBlock *b = buf.reader()->block.get();
+ char *current_block = buf.reader()->start();
// Dynamic TLS record sizing
ink_hrtime now = 0;
@@ -674,21 +661,17 @@ SSLNetVConnection::load_buffer_and_write(int64_t towrite, int64_t &wattempted, i
}
if (HttpProxyPort::TRANSPORT_BLIND_TUNNEL == this->attributes) {
- return this->super::load_buffer_and_write(towrite, wattempted, total_written, buf, needs);
+ return this->super::load_buffer_and_write(towrite, buf, total_written, needs);
}
bool trace = getSSLTrace();
Debug("ssl", "trace=%s", trace ? "TRUE" : "FALSE");
do {
- // check if we have done this block
- l = b->read_avail();
- l -= offset;
- if (l <= 0) {
- offset = -l;
- b = b->next.get();
- continue;
- }
+ // What is remaining left in the next block?
+ l = buf.reader()->block_read_avail();
+ current_block = buf.reader()->start();
+
// check if to amount to write exceeds that in this buffer
int64_t wavail = towrite - total_written;
@@ -699,7 +682,6 @@ SSLNetVConnection::load_buffer_and_write(int64_t towrite, int64_t &wattempted, i
// TS-2365: If the SSL max record size is set and we have
// more data than that, break this into smaller write
// operations.
- int64_t orig_l = l;
if (SSLConfigParams::ssl_maxrecord > 0 && l > SSLConfigParams::ssl_maxrecord) {
l = SSLConfigParams::ssl_maxrecord;
} else if (SSLConfigParams::ssl_maxrecord == -1) {
@@ -719,50 +701,39 @@ SSLNetVConnection::load_buffer_and_write(int64_t towrite, int64_t &wattempted, i
break;
}
- wattempted = l;
- total_written += l;
+ try_to_write = l;
+ num_really_written = 0;
Debug("ssl", "SSLNetVConnection::loadBufferAndCallWrite, before SSLWriteBuffer, l=%" PRId64 ", towrite=%" PRId64 ", b=%p", l,
- towrite, b);
- err = SSLWriteBuffer(ssl, b->start() + offset, l, r);
+ towrite, current_block);
+ err = SSLWriteBuffer(ssl, current_block, l, num_really_written);
if (!origin_trace) {
- TraceOut((0 < r && trace), get_remote_addr(), get_remote_port(), "WIRE TRACE\tbytes=%d\n%.*s", (int)r, (int)r,
- b->start() + offset);
+ TraceOut((0 < num_really_written && trace), get_remote_addr(), get_remote_port(), "WIRE TRACE\tbytes=%d\n%.*s",
+ (int)num_really_written, (int)num_really_written, current_block);
} else {
char origin_trace_ip[INET6_ADDRSTRLEN];
ats_ip_ntop(origin_trace_addr, origin_trace_ip, sizeof(origin_trace_ip));
- TraceOut((0 < r && trace), get_remote_addr(), get_remote_port(), "CLIENT %s:%d\ttbytes=%d\n%.*s", origin_trace_ip,
- origin_trace_port, (int)r, (int)r, b->start() + offset);
+ TraceOut((0 < num_really_written && trace), get_remote_addr(), get_remote_port(), "CLIENT %s:%d\ttbytes=%d\n%.*s",
+ origin_trace_ip, origin_trace_port, (int)num_really_written, (int)num_really_written, current_block);
}
- if (r == l) {
- wattempted = total_written;
- }
- if (l == orig_l) {
- // on to the next block
- offset = 0;
- b = b->next.get();
- } else {
- offset += l;
+ // We wrote all that we thought we should
+ if (num_really_written > 0) {
+ total_written += num_really_written;
+ buf.reader()->consume(num_really_written);
}
- Debug("ssl", "SSLNetVConnection::loadBufferAndCallWrite,Number of bytes written=%" PRId64 " , total=%" PRId64 "", r,
- total_written);
+ Debug("ssl", "SSLNetVConnection::loadBufferAndCallWrite,Number of bytes written=%" PRId64 " , total=%" PRId64 "",
+ num_really_written, total_written);
NET_INCREMENT_DYN_STAT(net_calls_to_write_stat);
- } while (r == l && total_written < towrite && b);
+ } while (num_really_written == try_to_write && total_written < towrite);
- if (r > 0) {
+ if (total_written > 0) {
sslLastWriteTime = now;
sslTotalBytesSent += total_written;
- if (total_written != wattempted) {
- Debug("ssl", "SSLNetVConnection::loadBufferAndCallWrite, wrote some bytes, but not all requested.");
- // I'm not sure how this could happen. We should have tried and hit an EAGAIN.
- needs |= EVENTIO_WRITE;
- return (r);
- } else {
- Debug("ssl", "SSLNetVConnection::loadBufferAndCallWrite, write successful.");
- return (total_written);
- }
+ }
+ if (num_really_written > 0) {
+ needs |= EVENTIO_WRITE;
} else {
switch (err) {
case SSL_ERROR_NONE:
@@ -770,7 +741,7 @@ SSLNetVConnection::load_buffer_and_write(int64_t towrite, int64_t &wattempted, i
break;
case SSL_ERROR_WANT_READ:
needs |= EVENTIO_READ;
- r = -EAGAIN;
+ num_really_written = -EAGAIN;
SSL_INCREMENT_DYN_STAT(ssl_error_want_read);
Debug("ssl.error", "SSL_write-SSL_ERROR_WANT_READ");
break;
@@ -784,20 +755,20 @@ SSLNetVConnection::load_buffer_and_write(int64_t towrite, int64_t &wattempted, i
}
needs |= EVENTIO_WRITE;
- r = -EAGAIN;
+ num_really_written = -EAGAIN;
Debug("ssl.error", "SSL_write-SSL_ERROR_WANT_WRITE");
break;
}
case SSL_ERROR_SYSCALL:
TraceOut(trace, get_remote_addr(), get_remote_port(), "Syscall Error: %s", strerror(errno));
- r = -errno;
+ num_really_written = -errno;
SSL_INCREMENT_DYN_STAT(ssl_error_syscall);
Debug("ssl.error", "SSL_write-SSL_ERROR_SYSCALL");
break;
// end of stream
case SSL_ERROR_ZERO_RETURN:
TraceOut(trace, get_remote_addr(), get_remote_port(), "SSL Error: zero return");
- r = -errno;
+ num_really_written = -errno;
SSL_INCREMENT_DYN_STAT(ssl_error_zero_return);
Debug("ssl.error", "SSL_write-SSL_ERROR_ZERO_RETURN");
break;
@@ -808,12 +779,12 @@ SSLNetVConnection::load_buffer_and_write(int64_t towrite, int64_t &wattempted, i
ERR_error_string_n(e, buf, sizeof(buf));
TraceIn(trace, get_remote_addr(), get_remote_port(), "SSL Error: sslErr=%d, ERR_get_error=%ld (%s) errno=%d", err, e, buf,
errno);
- r = -errno;
+ num_really_written = -errno;
SSL_CLR_ERR_INCR_DYN_STAT(this, ssl_error_ssl, "SSL_write-SSL_ERROR_SSL errno=%d", errno);
} break;
}
- return (r);
}
+ return num_really_written;
}
SSLNetVConnection::SSLNetVConnection()
diff --git a/iocore/net/UnixNetVConnection.cc b/iocore/net/UnixNetVConnection.cc
index 2a903cf..b52985c 100644
--- a/iocore/net/UnixNetVConnection.cc
+++ b/iocore/net/UnixNetVConnection.cc
@@ -510,17 +510,15 @@ write_to_net_io(NetHandler *nh, UnixNetVConnection *vc, EThread *thread)
return;
}
- int64_t total_written = 0, wattempted = 0;
int needs = 0;
- int64_t r = vc->load_buffer_and_write(towrite, wattempted, total_written, buf, needs);
+ int64_t total_written = 0;
+ int64_t r = vc->load_buffer_and_write(towrite, buf, total_written, needs);
- // if we have already moved some bytes successfully, summarize in r
- if (total_written != wattempted) {
- if (r <= 0)
- r = total_written - wattempted;
- else
- r = total_written - wattempted + r;
+ if (total_written > 0) {
+ NET_SUM_DYN_STAT(net_write_bytes_stat, total_written);
+ s->vio.ndone += total_written;
}
+
// check for errors
if (r <= 0) { // if the socket was not ready,add to WaitList
if (r == -EAGAIN || r == -ENOTCONN) {
@@ -543,19 +541,11 @@ write_to_net_io(NetHandler *nh, UnixNetVConnection *vc, EThread *thread)
return;
}
vc->write.triggered = 0;
- write_signal_error(nh, vc, (int)-r);
+ write_signal_error(nh, vc, (int)-total_written);
return;
- } else {
+ } else { // Wrote data. Finished without error
int wbe_event = vc->write_buffer_empty_event; // save so we can clear if needed.
- NET_SUM_DYN_STAT(net_write_bytes_stat, r);
-
- // Remove data from the buffer and signal continuation.
- ink_assert(buf.reader()->read_avail() >= r);
- buf.reader()->consume(r);
- ink_assert(buf.reader()->read_avail() >= 0);
- s->vio.ndone += r;
-
// If the empty write buffer trap is set, clear it.
if (!(buf.reader()->is_read_avail_more_than(0)))
vc->write_buffer_empty_event = 0;
@@ -946,28 +936,22 @@ UnixNetVConnection::net_read_io(NetHandler *nh, EThread *lthread)
// (SSL read does not support overlapped i/o)
// without duplicating all the code in write_to_net.
int64_t
-UnixNetVConnection::load_buffer_and_write(int64_t towrite, int64_t &wattempted, int64_t &total_written, MIOBufferAccessor &buf,
- int &needs)
+UnixNetVConnection::load_buffer_and_write(int64_t towrite, MIOBufferAccessor &buf, int64_t &total_written, int &needs)
{
int64_t r = 0;
-
- // XXX Rather than dealing with the block directly, we should use the IOBufferReader API.
- int64_t offset = buf.reader()->start_offset;
- IOBufferBlock *b = buf.reader()->block.get();
+ int64_t try_to_write = 0;
+ IOBufferReader *tmp_reader = buf.reader()->clone();
do {
IOVec tiovec[NET_MAX_IOV];
unsigned niov = 0;
- int64_t total_written_last = total_written;
- while (b && niov < NET_MAX_IOV) {
+ try_to_write = 0;
+ while (niov < NET_MAX_IOV) {
// check if we have done this block
- int64_t l = b->read_avail();
- l -= offset;
- if (l <= 0) {
- offset = -l;
- b = b->next.get();
- continue;
- }
+ int64_t l = tmp_reader->block_read_avail();
+ if (l <= 0)
+ break;
+ char *current_block = tmp_reader->start();
// check if to amount to write exceeds that in this buffer
int64_t wavail = towrite - total_written;
@@ -979,18 +963,14 @@ UnixNetVConnection::load_buffer_and_write(int64_t towrite, int64_t &wattempted,
break;
}
- total_written += l;
// build an iov entry
tiovec[niov].iov_len = l;
- tiovec[niov].iov_base = b->start() + offset;
+ try_to_write += l;
+ tiovec[niov].iov_base = current_block;
niov++;
- // on to the next block
- offset = 0;
- b = b->next.get();
+ tmp_reader->consume(l);
}
- wattempted = total_written - total_written_last;
-
ink_assert(niov > 0);
ink_assert(niov <= countof(tiovec));
r = socketManager.writev(con.fd, &tiovec[0], niov);
@@ -1011,14 +991,20 @@ UnixNetVConnection::load_buffer_and_write(int64_t towrite, int64_t &wattempted,
strerror(errno));
}
}
+ if (r > 0) {
+ buf.reader()->consume(r);
+ }
+ total_written += r;
ProxyMutex *mutex = thread->mutex.get();
NET_INCREMENT_DYN_STAT(net_calls_to_write_stat);
- } while (r == wattempted && total_written < towrite);
+ } while (r == try_to_write && total_written < towrite);
+
+ tmp_reader->dealloc();
needs |= EVENTIO_WRITE;
- return (r);
+ return r;
}
void
--
To stop receiving notification emails like this one, please contact
['"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>'].