From: Marko Kreen Date: Fri, 4 Dec 2015 10:14:03 +0000 (+0200) Subject: sbuf: improved sbuf_loopcnt logic X-Git-Tag: pgbouncer_1_7~4 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=09e7ab43136fcf2f7ad84f03cb2053506f64efbf;p=pgbouncer sbuf: improved sbuf_loopcnt logic Simple early exit won't work for TLS as all data may be in libssl buffers and no network wakeup is coming. Use special-case event_add() with timeout for postponing. It might be even improve non-tls case as there could be specific buffers lengths when even that does postponing while nothing is coming from network. --- diff --git a/src/sbuf.c b/src/sbuf.c index b651717..5c89ffe 100644 --- a/src/sbuf.c +++ b/src/sbuf.c @@ -409,6 +409,42 @@ static bool sbuf_wait_for_data(SBuf *sbuf) return true; } +static void sbuf_recv_forced_cb(int sock, short flags, void *arg) +{ + SBuf *sbuf = arg; + + sbuf->wait_type = W_NONE; + + if (sbuf_wait_for_data(sbuf)) { + sbuf_recv_cb(sock, flags, arg); + } else { + sbuf_call_proto(sbuf, SBUF_EV_RECV_FAILED); + } +} + +static bool sbuf_wait_for_data_forced(SBuf *sbuf) +{ + int err; + struct timeval tv_min; + + tv_min.tv_sec = 0; + tv_min.tv_usec = 1; + + if (sbuf->wait_type != W_NONE) { + event_del(&sbuf->ev); + sbuf->wait_type = W_NONE; + } + + event_set(&sbuf->ev, sbuf->sock, EV_READ, sbuf_recv_forced_cb, sbuf); + err = event_add(&sbuf->ev, &tv_min); + if (err < 0) { + log_warning("sbuf_wait_for_data: event_add failed: %s", strerror(errno)); + return false; + } + sbuf->wait_type = W_ONCE; + return true; +} + /* libevent EV_WRITE: called when dest socket is writable again */ static void sbuf_send_cb(int sock, short flags, void *arg) { @@ -686,6 +722,8 @@ try_more: * after resync to process all data. (result is ignored) */ ok = sbuf_process_pending(sbuf); + + sbuf_wait_for_data_forced(sbuf); return; } loopcnt++;