]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
Improve client/listen curl transfer speed at low FPS
authorbones_was_here <bones_was_here@xonotic.au>
Sat, 21 Jan 2023 01:49:27 +0000 (11:49 +1000)
committerbones_was_here <bones_was_here@xonotic.au>
Sat, 21 Jan 2023 01:49:27 +0000 (11:49 +1000)
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 <bones_was_here@xonotic.au>
cl_main.c
host.c
libcurl.c
libcurl.h

index 2f00941e0371506df1a693878eadc1e25576b904..dd2ea6a5911a2d1aca0935e44efe742cfba1f5df 100644 (file)
--- 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 aa8fb4c32bf9d712113f2bce98d71ec6d06f77e9..e34f712bebb2e148456af2f1e7afe2a71adb7739 100644 (file)
--- 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;
index 3ad3c5ff87418c237dddc284aa5ac5b33a2cac9e..53674299a8a603388088bb15e635a2dc164f636f 100644 (file)
--- 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
index d960be8af0939c7c97eb19293e5bbe4657b75ecd..21b8c6fe9f331cbfd2f31ba83e272736cbf4aad0 100644 (file)
--- 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);