summaryrefslogtreecommitdiffstats
path: root/proxy
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 /proxy
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.
Diffstat (limited to 'proxy')
-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) {