From 2b81a48b4572ac02fd7143d7636d83e7e8a4b8a9 Mon Sep 17 00:00:00 2001 From: Heikki Hannikainen Date: Sun, 14 Oct 2012 11:15:13 +0300 Subject: [PATCH] Do not drop clients on the initial EAGAIN|EWOULDBLOCK write error, buffer packets instead. The error happens even when the per-socket kernel buffer limit is not met (only hundreds of bytes written). --- src/worker.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/worker.c b/src/worker.c index d157d13..6e47676 100644 --- a/src/worker.c +++ b/src/worker.c @@ -882,9 +882,10 @@ int client_write(struct worker_t *self, struct client_t *c, char *p, int len) if (i < 0 && (e == EAGAIN || e == EWOULDBLOCK)) { /* Kernel's transmit buffer is full. They're pretty * big, so we'll assume the client is dead and disconnect. + * Use "buffer overflow" as error message. */ hlog(LOG_DEBUG, "client_write(%s) fails/2a; disconnecting; %s", c->addr_rem, strerror(e)); - client_close(self, c, e); + client_close(self, c, CLIERR_OUTPUT_BUFFER_FULL); return -10; } if (i < 0) { @@ -934,12 +935,14 @@ int client_write(struct worker_t *self, struct client_t *c, char *p, int len) return -9; } if (i < 0 && (e == EAGAIN || e == EWOULDBLOCK)) { - /* Kernel's transmit buffer is full. They're pretty - * big, so we'll assume the client is dead and disconnect. + /* Kernel's transmit buffer is full (per-socket or some more global resource). + * This happens even with small amounts of data in real world: + * aprsc INFO: Client xx.yy.zz.ff:22823 (XXXXX) closed after 1 s: + * Resource temporarily unavailable, tx/rx 735/51 bytes 8/0 pkts, + * dropped 0, fd 59, worker 1 app aprx ver 2.00 */ - hlog(LOG_DEBUG, "client_write(%s) fails/2c; disconnecting; %s", c->addr_rem, strerror(e)); - client_close(self, c, e); - return -10; + hlog(LOG_DEBUG, "client_write(%s) fails/2c; %s", c->addr_rem, strerror(e)); + return -1; } if (i < 0 && len != 0) { hlog(LOG_DEBUG, "client_write(%s) fails/2d; disconnecting; %s", c->addr_rem, strerror(e));