diff options
author | Simo Sorce <simo@redhat.com> | 2012-03-21 20:20:27 -0400 |
---|---|---|
committer | Simo Sorce <simo@redhat.com> | 2012-03-22 02:33:52 -0400 |
commit | 9714cbbf07093e7b6661d8fb93c0b00172d3d677 (patch) | |
tree | 492d35801acf44c44891d67674ef08f83fda85ad | |
parent | 402e927b928f5d51d36df72f69211fbc5a2136c8 (diff) | |
download | gss-proxy-9714cbbf07093e7b6661d8fb93c0b00172d3d677.tar.gz gss-proxy-9714cbbf07093e7b6661d8fb93c0b00172d3d677.tar.xz gss-proxy-9714cbbf07093e7b6661d8fb93c0b00172d3d677.zip |
gp_socket: Optimize sending data with writev
Turns out the Linux kernel expects to get the whole reply in a single
operation. This optimizes the code to call one less syscall and makes it also
more compact. So let's please the kernel and get better code in place.
-rw-r--r-- | proxy/src/gp_socket.c | 43 |
1 files changed, 22 insertions, 21 deletions
diff --git a/proxy/src/gp_socket.c b/proxy/src/gp_socket.c index e727715..a8d3a55 100644 --- a/proxy/src/gp_socket.c +++ b/proxy/src/gp_socket.c @@ -362,41 +362,32 @@ void gp_socket_send_data(verto_ctx *vctx, struct gp_conn *conn, static void gp_socket_write(verto_ctx *vctx, verto_ev *ev) { struct gp_buffer *wbuf; + struct iovec iov[2]; uint32_t size; ssize_t wn; + int vecs; int fd; fd = verto_get_fd(ev); wbuf = verto_get_private(ev); + vecs = 0; + if (wbuf->pos == 0) { /* first write, send the buffer size as packet header */ size = htonl(wbuf->size); - errno = 0; - wn = write(fd, &size, sizeof(uint32_t)); - if (wn == -1) { - if (errno == EAGAIN || errno == EINTR) { - /* try again later */ - gp_socket_schedule_write(vctx, wbuf); - } else { - /* error on socket, close and release it */ - gp_conn_free(wbuf->conn); - gp_buffer_free(wbuf); - } - return; - } - if (wn != 4) { - /* don't bother trying to handle sockets that can't - * buffer even 4 bytes */ - gp_conn_free(wbuf->conn); - gp_buffer_free(wbuf); - return; - } + iov[0].iov_base = &size; + iov[0].iov_len = sizeof(size); + vecs = 1; } + iov[vecs].iov_base = wbuf->data + wbuf->pos; + iov[vecs].iov_len = wbuf->size - wbuf->pos; + vecs++; + errno = 0; - wn = write(fd, wbuf->data + wbuf->pos, wbuf->size - wbuf->pos); + wn = writev(fd, iov, vecs); if (wn == -1) { if (errno == EAGAIN || errno == EINTR) { /* try again later */ @@ -408,6 +399,16 @@ static void gp_socket_write(verto_ctx *vctx, verto_ev *ev) } return; } + if (vecs == 2) { + if (wn < sizeof(size)) { + /* don't bother trying to handle sockets that can't + * buffer even 4 bytes */ + gp_conn_free(wbuf->conn); + gp_buffer_free(wbuf); + return; + } + wn -= sizeof(size); + } wbuf->pos += wn; if (wbuf->size > wbuf->pos) { |