Simplify evbuffer_write logic: combine nearly all of WSASend and writev cases.

svn:r1004
This commit is contained in:
Nick Mathewson 2009-01-14 14:58:48 +00:00
parent bab8f2e182
commit 6d3ed0657d
2 changed files with 55 additions and 55 deletions

106
buffer.c
View File

@ -888,6 +888,27 @@ evbuffer_read(struct evbuffer *buf, evutil_socket_t fd, int howmuch)
return (n); return (n);
} }
#if defined(HAVE_SYS_UIO_H)
#define USE_IOVEC_IMPL
#endif
#ifdef USE_IOVEC_IMPL
#ifdef HAVE_SYS_UIO_H
/* number of iovec we use for writev, fragmentation is going to determine
* how much we end up writing */
#define NUM_IOVEC 128
#define IOV_TYPE struct iovec
#define IOV_PTR_FIELD iov_base
#define IOV_LEN_FIELD iov_len
#else
#define NUM_IOVEC 16
#define IOV_TYPE WSABUF
#define IOV_PTR_FIELD buf
#define IOV_LEN_FIELD len
#endif
#endif
int int
evbuffer_write_atmost(struct evbuffer *buffer, evutil_socket_t fd, evbuffer_write_atmost(struct evbuffer *buffer, evutil_socket_t fd,
ssize_t howmuch) ssize_t howmuch)
@ -898,60 +919,43 @@ evbuffer_write_atmost(struct evbuffer *buffer, evutil_socket_t fd,
howmuch = buffer->total_len; howmuch = buffer->total_len;
{ {
#ifndef WIN32 #ifdef USE_IOVEC_IMPL
#ifdef HAVE_SYS_UIO_H IOV_TYPE iov[NUM_IOVEC];
struct iovec iov[NUM_IOVEC]; struct evbuffer_chain *chain = buffer->first;
struct evbuffer_chain *chain = buffer->first; int i = 0;
int i = 0; /* XXX make this top out at some maximal data length? if the buffer has
/* XXX make this top out at some maximal data length? if the buffer has * (say) 1MB in it, split over 128 chains, there's no way it all gets
* (say) 1MB in it, split over 128 chains, there's no way it all gets * written in one go. */
* written in one go. */ while (chain != NULL && i < NUM_IOVEC && howmuch) {
while (chain != NULL && i < NUM_IOVEC && howmuch) { iov[i].IOV_PTR_FIELD = chain->buffer + chain->misalign;
iov[i].iov_base = chain->buffer + chain->misalign; if (howmuch >= chain->off) {
if (howmuch >= chain->off) { iov[i++].IOV_LEN_FIELD = chain->off;
iov[i++].iov_len = chain->off; howmuch -= chain->off;
howmuch -= chain->off; } else {
} else { iov[i++].IOV_LEN_FIELD = howmuch;
iov[i++].iov_len = howmuch; break;
break; }
chain = chain->next;
} }
chain = chain->next; #ifdef WIN32
} {
n = writev(fd, iov, i); DWORD byteSent;
#else /* !HAVE_SYS_UIO_H */ if (WSASend(fd, buffers, i, &bytesSent, 0, NULL, NULL))
void *p = evbuffer_pullup(buffer, howmuch); n = -1;
n = write(fd, p, howmuch, 0); else
n = bytesSent;
}
#else
n = writev(fd, iov, i);
#endif #endif
#elif 0 #elif defined(WIN32)
const int N_BUFFERS = 8; /* XXX(nickm) Don't disable this code until we know if the WSARecv
WSABUF buffers[N_BUFFERS]; * code above works. */
struct evbuffer_chain *chain = buffer->first; void *p = evbuffer_pullup(buffer, howmuch);
int i = 0; n = send(fd, p, howmuch, 0);
DWORD bytesSent;
/* XXX make this top out at some maximal data length? if the buffer has
* (say) 1MB in it, split over 128 chains, there's no way it all gets
* written in one go. */
while (chain != NULL && i < N_BUFFERS && howmuch) {
buffers[i].buf = chain->buffer + chain->misalign;
if (howmuch >= chain->off) {
buffers[i++].len = chain->off;
howmuch -= chain->off;
} else {
buffers[i++].len = howmuch;
break;
}
chain = chain->next;
}
if (WSASend(fd, buffers, i, &bytesSent, 0, NULL, NULL))
n = -1;
else
n = bytesSent;
#else #else
/* XXX(nickm) Don't disable this code until we know if the WSARecv void *p = evbuffer_pullup(buffer, howmuch);
* code above works. */ n = write(fd, p, howmuch);
void *p = evbuffer_pullup(buffer, howmuch);
n = send(fd, p, howmuch, 0);
#endif #endif
} }

View File

@ -37,10 +37,6 @@ extern "C" {
/* minimum allocation */ /* minimum allocation */
#define MIN_BUFFER_SIZE 256 #define MIN_BUFFER_SIZE 256
/* number of iovec we use for writev, fragmentation is going to determine
* how much we end up writing */
#define NUM_IOVEC 128
struct evbuffer_chain; struct evbuffer_chain;
struct evbuffer { struct evbuffer {
struct evbuffer_chain *first; struct evbuffer_chain *first;