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);
}
#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
evbuffer_write_atmost(struct evbuffer *buffer, evutil_socket_t fd,
ssize_t howmuch)
@ -898,60 +919,43 @@ evbuffer_write_atmost(struct evbuffer *buffer, evutil_socket_t fd,
howmuch = buffer->total_len;
{
#ifndef WIN32
#ifdef HAVE_SYS_UIO_H
struct iovec iov[NUM_IOVEC];
struct evbuffer_chain *chain = buffer->first;
int i = 0;
/* 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 < NUM_IOVEC && howmuch) {
iov[i].iov_base = chain->buffer + chain->misalign;
if (howmuch >= chain->off) {
iov[i++].iov_len = chain->off;
howmuch -= chain->off;
} else {
iov[i++].iov_len = howmuch;
break;
#ifdef USE_IOVEC_IMPL
IOV_TYPE iov[NUM_IOVEC];
struct evbuffer_chain *chain = buffer->first;
int i = 0;
/* 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 < NUM_IOVEC && howmuch) {
iov[i].IOV_PTR_FIELD = chain->buffer + chain->misalign;
if (howmuch >= chain->off) {
iov[i++].IOV_LEN_FIELD = chain->off;
howmuch -= chain->off;
} else {
iov[i++].IOV_LEN_FIELD = howmuch;
break;
}
chain = chain->next;
}
chain = chain->next;
}
n = writev(fd, iov, i);
#else /* !HAVE_SYS_UIO_H */
void *p = evbuffer_pullup(buffer, howmuch);
n = write(fd, p, howmuch, 0);
#ifdef WIN32
{
DWORD byteSent;
if (WSASend(fd, buffers, i, &bytesSent, 0, NULL, NULL))
n = -1;
else
n = bytesSent;
}
#else
n = writev(fd, iov, i);
#endif
#elif 0
const int N_BUFFERS = 8;
WSABUF buffers[N_BUFFERS];
struct evbuffer_chain *chain = buffer->first;
int i = 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;
#elif defined(WIN32)
/* XXX(nickm) Don't disable this code until we know if the WSARecv
* code above works. */
void *p = evbuffer_pullup(buffer, howmuch);
n = send(fd, p, howmuch, 0);
#else
/* XXX(nickm) Don't disable this code until we know if the WSARecv
* code above works. */
void *p = evbuffer_pullup(buffer, howmuch);
n = send(fd, p, howmuch, 0);
void *p = evbuffer_pullup(buffer, howmuch);
n = write(fd, p, howmuch);
#endif
}

View File

@ -37,10 +37,6 @@ extern "C" {
/* minimum allocation */
#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 {
struct evbuffer_chain *first;