From 4a64b4f07b4bb56a8e7d560f543a99d8ae92bf65 Mon Sep 17 00:00:00 2001 From: Joris Vink Date: Thu, 13 Jun 2019 12:59:17 +0200 Subject: [PATCH] Improve curl timeout handling. In case libcurl instructs us to call the timeout function as soon as possible (timeout == 0 in curl_timeout), don't try to be clever with a timeout value of 10ms. Instead call the timeout function once we get back in the worker event loop. This makes things a lot snappier as we don't depend on epoll/kqueue waiting for io for 10ms (which actually isn't 10ms...). --- include/kore/curl.h | 1 + src/curl.c | 17 +++++++++++++++-- src/worker.c | 12 ++++++++++-- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/include/kore/curl.h b/include/kore/curl.h index 5bf9083..6f4257c 100644 --- a/include/kore/curl.h +++ b/include/kore/curl.h @@ -67,6 +67,7 @@ extern u_int16_t kore_curl_timeout; extern u_int64_t kore_curl_recv_max; void kore_curl_sysinit(void); +void kore_curl_do_timeout(void); void kore_curl_run(struct kore_curl *); void kore_curl_cleanup(struct kore_curl *); int kore_curl_success(struct kore_curl *); diff --git a/src/curl.c b/src/curl.c index a082f5a..5c9446b 100644 --- a/src/curl.c +++ b/src/curl.c @@ -33,6 +33,7 @@ struct fd_cache { static void curl_process(void); static void curl_event_handle(void *, int); +static void curl_timeout(void *, u_int64_t); static int curl_timer(CURLM *, long, void *); static int curl_socket(CURL *, curl_socket_t, int, void *, void *); @@ -43,6 +44,7 @@ static CURLM *multi = NULL; static struct kore_timer *timer = NULL; static struct kore_pool fd_cache_pool; static char user_agent[64]; +static int timeout_immediate = 0; static LIST_HEAD(, fd_cache) cache[FD_CACHE_BUCKETS]; u_int16_t kore_curl_timeout = KORE_CURL_TIMEOUT; @@ -146,6 +148,13 @@ kore_curl_cleanup(struct kore_curl *client) } } +void +kore_curl_do_timeout(void) +{ + while (timeout_immediate) + curl_timeout(NULL, kore_time_ms()); +} + size_t kore_curl_tobuf(char *ptr, size_t size, size_t nmemb, void *udata) { @@ -560,6 +569,8 @@ curl_timeout(void *uarg, u_int64_t now) static int curl_timer(CURLM *mctx, long timeout, void *arg) { + timeout_immediate = 0; + if (timeout < 0) { if (timer != NULL) { kore_timer_remove(timer); @@ -573,8 +584,10 @@ curl_timer(CURLM *mctx, long timeout, void *arg) timer = NULL; } - if (timeout == 0) - timeout = 10; + if (timeout == 0) { + timeout_immediate = 1; + return (CURLM_OK); + } timer = kore_timer_add(curl_timeout, timeout, mctx, KORE_TIMER_ONESHOT); diff --git a/src/worker.c b/src/worker.c index b11ab07..7f18158 100644 --- a/src/worker.c +++ b/src/worker.c @@ -49,6 +49,10 @@ #include "python_api.h" #endif +#if defined(KORE_USE_CURL) +#include "curl.h" +#endif + #if !defined(WAIT_ANY) #define WAIT_ANY (-1) #endif @@ -471,14 +475,18 @@ kore_worker_entry(struct kore_worker *kw) break; kore_timer_run(now); - +#if defined(KORE_USE_CURL) + kore_curl_do_timeout(); +#endif #if !defined(KORE_NO_HTTP) http_process(); #endif #if defined(KORE_USE_PYTHON) kore_python_coro_run(); #endif - +#if defined(KORE_USE_CURL) + kore_curl_do_timeout(); +#endif if (next_prune <= now) { kore_connection_check_timeout(now); kore_connection_prune(KORE_CONNECTION_PRUNE_DISCONNECT);