aboutsummaryrefslogtreecommitdiff
path: root/src/or/buffers.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2008-06-11 17:56:52 +0000
committerNick Mathewson <nickm@torproject.org>2008-06-11 17:56:52 +0000
commita886e86cbd634cdf1411bae5280eb7c5275d08da (patch)
tree31ab555f15dd59b3eeff7c1303b14acea42f3389 /src/or/buffers.c
parentb2fcc417d4e515059018f282149f95df9bd6caab (diff)
downloadtor-a886e86cbd634cdf1411bae5280eb7c5275d08da.tar.gz
tor-a886e86cbd634cdf1411bae5280eb7c5275d08da.zip
r16171@tombo: nickm | 2008-06-11 13:47:41 -0400
Lower number of syscalls used to write data to ordinary sockets through use of writev. Disabled till I have time to test it. svn:r15133
Diffstat (limited to 'src/or/buffers.c')
-rw-r--r--src/or/buffers.c61
1 files changed, 57 insertions, 4 deletions
diff --git a/src/or/buffers.c b/src/or/buffers.c
index daef1f9357..0f7623a4ce 100644
--- a/src/or/buffers.c
+++ b/src/or/buffers.c
@@ -15,6 +15,13 @@ const char buffers_c_id[] =
**/
#define BUFFERS_PRIVATE
#include "or.h"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+
//#define PARANOIA
//#define NOINLINE
@@ -545,6 +552,9 @@ buf_add_chunk_with_capacity(buf_t *buf, size_t capacity, int capped)
return chunk;
}
+/** DOCDOC */
+#define N_IOV 3
+
/** Read up to <b>at_most</b> bytes from the socket <b>fd</b> into
* <b>chunk</b> (which must be on <b>buf</b>). If we get an EOF, set
* *<b>reached_eof</b> to 1. Return -1 on error, 0 on eof or blocking,
@@ -554,9 +564,26 @@ read_to_chunk(buf_t *buf, chunk_t *chunk, int fd, size_t at_most,
int *reached_eof)
{
ssize_t read_result;
-
- tor_assert(CHUNK_REMAINING_CAPACITY(chunk) >= at_most);
+#if 0 && defined(HAVE_READV) && !defined(WIN32)
+ struct iovec iov[N_IOV];
+ int i;
+ size_t remaining = at_most;
+ for (i=0; chunk && i < N_IOV && remaining; ++i) {
+ iov[i].iov_base = CHUNK_WRITE_PTR(chunk);
+ if (remaining > CHUNK_REMAINING_CAPACITY(chunk))
+ iov[i].iov_len = CHUNK_REMAINING_CAPACITY(chunk);
+ else
+ iov[i].iov_len = remaining;
+ remaining -= iov[i].iov_len;
+ chunk = chunk->next;
+ }
+ read_result = readv(fd, iov, i);
+#else
+ if (at_most > CHUNK_REMAINING_CAPACITY(chunk))
+ at_most = CHUNK_REMAINING_CAPACITY(chunk);
read_result = tor_socket_recv(fd, CHUNK_WRITE_PTR(chunk), at_most, 0);
+#endif
+
if (read_result < 0) {
int e = tor_socket_errno(fd);
if (!ERRNO_IS_EAGAIN(e)) { /* it's a real error */
@@ -573,6 +600,14 @@ read_to_chunk(buf_t *buf, chunk_t *chunk, int fd, size_t at_most,
return 0;
} else { /* actually got bytes. */
buf->datalen += read_result;
+#if 0 && defined(HAVE_READV) && !defined(WIN32)
+ while ((size_t)read_result > CHUNK_REMAINING_CAPACITY(chunk)) {
+ chunk->datalen += CHUNK_REMAINING_CAPACITY(chunk);
+ read_result -= CHUNK_REMAINING_CAPACITY(chunk);
+ chunk = chunk->next;
+ tor_assert(chunk);
+ }
+#endif
chunk->datalen += read_result;
log_debug(LD_NET,"Read %ld bytes. %d on inbuf.", (long)read_result,
(int)buf->datalen);
@@ -707,9 +742,27 @@ flush_chunk(int s, buf_t *buf, chunk_t *chunk, size_t sz,
size_t *buf_flushlen)
{
ssize_t write_result;
-
- tor_assert(sz <= chunk->datalen);
+#if 0 && defined(HAVE_WRITEV) && !defined(WIN32)
+ struct iovec iov[N_IOV];
+ int i;
+ size_t remaining = sz;
+ for (i=0; chunk && i < N_IOV && remaining; ++i) {
+ iov[i].iov_base = chunk->data;
+ if (remaining > chunk->datalen)
+ iov[i].iov_len = chunk->datalen;
+ else
+ iov[i].iov_len = remaining;
+ remaining -= iov[i].iov_len;
+ chunk = chunk->next;
+ }
+ write_result = writev(s, iov, i);
+#else
+ if (sz > chunk->datalen)
+ sz = chunk->datalen;
write_result = tor_socket_send(s, chunk->data, sz, 0);
+#endif
+
+
if (write_result < 0) {
int e = tor_socket_errno(s);
if (!ERRNO_IS_EAGAIN(e)) { /* it's a real error */