summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2012-03-21 20:20:27 -0400
committerSimo Sorce <simo@redhat.com>2012-03-22 02:33:52 -0400
commit9714cbbf07093e7b6661d8fb93c0b00172d3d677 (patch)
tree492d35801acf44c44891d67674ef08f83fda85ad
parent402e927b928f5d51d36df72f69211fbc5a2136c8 (diff)
downloadgss-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.c43
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) {