From: bones_was_here Date: Sat, 21 Jan 2023 01:49:27 +0000 (+1000) Subject: Improve client/listen curl transfer speed at low FPS X-Git-Url: https://git.xonotic.org/?a=commitdiff_plain;h=025fbac31da7f654e296e20b3037b5ce88074f8b;hp=a2bb7fbbe9c477aaa2ebb4d9aaa2fa0423dd6f0a;p=xonotic%2Fdarkplaces.git Improve client/listen curl transfer speed at low FPS This is a huge boost for some libcurl versions, eg 7.74 in Debian 11 Fixes https://gitlab.com/xonotic/darkplaces/-/issues/375 Signed-off-by: bones_was_here --- diff --git a/cl_main.c b/cl_main.c index 2f00941e..dd2ea6a5 100644 --- a/cl_main.c +++ b/cl_main.c @@ -2814,6 +2814,11 @@ double CL_Frame (double time) SndSys_SendKeyEvents(); Sys_SendKeyEvents(); + /* + * If the accumulator hasn't become positive, don't + * run the frame. Everything that happens before this + * point will happen even if we're sleeping this frame. + */ if((cl_timer += time) < 0) return cl_timer; diff --git a/host.c b/host.c index aa8fb4c3..e34f712b 100644 --- a/host.c +++ b/host.c @@ -681,7 +681,11 @@ static inline void Host_Sleep(double time) // TODO can we do the same for ServerFrame? Probably not. } else + { + if (cls.state != ca_dedicated) + Curl_Select(&time); Sys_Sleep((int)time); + } delta = Sys_DirtyTime() - time0; if (delta < 0 || delta >= 1800) delta = 0; diff --git a/libcurl.c b/libcurl.c index 3ad3c5ff..53674299 100644 --- a/libcurl.c +++ b/libcurl.c @@ -158,6 +158,7 @@ static const char * (*qcurl_easy_strerror) (CURLcode); static CURLM * (*qcurl_multi_init) (void); static CURLMcode (*qcurl_multi_perform) (CURLM *multi_handle, int *running_handles); +static CURLMcode (*qcurl_multi_poll) (CURLM *multi_handle, void*, unsigned int extra_nfds, int timeout_ms, int *ret); static CURLMcode (*qcurl_multi_add_handle) (CURLM *multi_handle, CURL *easy_handle); static CURLMcode (*qcurl_multi_remove_handle) (CURLM *multi_handle, CURL *easy_handle); static CURLMsg * (*qcurl_multi_info_read) (CURLM *multi_handle, int *msgs_in_queue); @@ -177,6 +178,7 @@ static dllfunction_t curlfuncs[] = {"curl_easy_getinfo", (void **) &qcurl_easy_getinfo}, {"curl_multi_init", (void **) &qcurl_multi_init}, {"curl_multi_perform", (void **) &qcurl_multi_perform}, + {"curl_multi_poll", (void **) &qcurl_multi_poll}, {"curl_multi_add_handle", (void **) &qcurl_multi_add_handle}, {"curl_multi_remove_handle",(void **) &qcurl_multi_remove_handle}, {"curl_multi_info_read", (void **) &qcurl_multi_info_read}, @@ -432,6 +434,8 @@ static size_t CURL_fwrite(void *data, size_t size, size_t nmemb, void *vdi) di->bytes_received += bytes; + //Con_Printf("CURL_fwrite callback timestamp: %f bytes: %ld\n", host.realtime, ret); + return ret; // Why not ret / nmemb? // Because CURLOPT_WRITEFUNCTION docs say to return the number of bytes. @@ -1235,6 +1239,25 @@ void Curl_Frame(void) if (curl_mutex) Thread_UnlockMutex(curl_mutex); } +/* +==================== +Curl_Select + +Sleeps until there's some transfer progress or a timeout is reached, +unfortunately the timeout is only in milliseconds. +This allows good throughput even at very low FPS. +==================== +*/ +void Curl_Select(double *microseconds) +{ + if (List_Is_Empty(&downloads)) + return; + if (qcurl_multi_poll(curlm, NULL, 0, *microseconds / 1000, NULL) == CURLM_OK) + *microseconds = 0; // either we finished waiting or a transfer progressed + else + Con_Print("There's an emergency going on!\nIt's still going on!\nMaybe you need to upgrade libcurl?\n"); +} + /* ==================== Curl_CancelAll diff --git a/libcurl.h b/libcurl.h index d960be8a..21b8c6fe 100644 --- a/libcurl.h +++ b/libcurl.h @@ -14,6 +14,7 @@ typedef void (*curl_callback_t) (int status, size_t length_received, unsigned ch // code is one of the CURLCBSTATUS constants, or the HTTP error code (when > 0). void Curl_Frame(void); +void Curl_Select(double *microseconds); qbool Curl_Running(void); qbool Curl_Begin_ToFile(const char *URL, double maxspeed, const char *name, int loadtype, qbool forthismap);