]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
cbuf: recycle node after it executes, clear commands on Host_Error()
authorbones_was_here <bones_was_here@xonotic.au>
Sat, 9 Dec 2023 07:49:56 +0000 (17:49 +1000)
committerbones_was_here <bones_was_here@xonotic.au>
Sat, 9 Dec 2023 10:13:36 +0000 (20:13 +1000)
This reverts 626658074c8dd5c2288becd836103e2efdb9b741 which looks like a
potentially racy or non-threadsafe approach, and instead prevents
problems by clearing the command buffers if Host_Error() is called and
doesn't shut down DP.

Signed-off-by: bones_was_here <bones_was_here@xonotic.au>
cmd.c
cmd.h
host.c

diff --git a/cmd.c b/cmd.c
index 66dfaa820001f788ffae651febc678bc23499e9b..e1e2c0a0dcfd5ce2236063875dddfaa3d96f42fe 100644 (file)
--- a/cmd.c
+++ b/cmd.c
@@ -406,10 +406,7 @@ void Cbuf_Execute (cmd_buf_t *cbuf)
                 * can insert data at the beginning of the text buffer
                 */
                current = List_Entry(cbuf->start.next, cmd_input_t, list);
-               
-               // Recycle memory so using WASD doesn't cause a malloc and free
-               List_Move_Tail(&current->list, &cbuf->free);
-               
+
                /*
                 * Assume we're rolling with the current command-line and
                 * always set this false because alias expansion or cbuf insertion
@@ -434,6 +431,9 @@ void Cbuf_Execute (cmd_buf_t *cbuf)
                        Cmd_ExecuteString (current->source, current->text, src_local, false);
                }
 
+               // Recycle memory so using WASD doesn't cause a malloc and free
+               List_Move_Tail(&current->list, &cbuf->free);
+
                current = NULL;
 
                if (cbuf->wait)
@@ -449,11 +449,7 @@ void Cbuf_Execute (cmd_buf_t *cbuf)
                if (++i == 1000000 && prvm_runawaycheck)
                {
                        Con_Printf(CON_WARN "Cbuf_Execute: runaway loop counter hit limit of %d commands, clearing command buffers!\n", i);
-                       while (!List_Is_Empty(&cbuf->start))
-                               List_Move_Tail(cbuf->start.next, &cbuf->free);
-                       while (!List_Is_Empty(&cbuf->deferred))
-                               List_Move_Tail(cbuf->deferred.next, &cbuf->free);
-                       cbuf->size = 0;
+                       Cbuf_Clear(cbuf);
                }
        }
 }
@@ -492,6 +488,15 @@ void Cbuf_Frame(cmd_buf_t *cbuf)
 //     R_TimeReport("console");
 }
 
+void Cbuf_Clear(cmd_buf_t *cbuf)
+{
+       while (!List_Is_Empty(&cbuf->start))
+               List_Move_Tail(cbuf->start.next, &cbuf->free);
+       while (!List_Is_Empty(&cbuf->deferred))
+               List_Move_Tail(cbuf->deferred.next, &cbuf->free);
+       cbuf->size = 0;
+}
+
 /*
 ==============================================================================
 
diff --git a/cmd.h b/cmd.h
index 99241fcf753618591fa61052398d2280119702d4..b3502919ab766fb74a1ac6989e72f7bea130e2a3 100644 (file)
--- a/cmd.h
+++ b/cmd.h
@@ -199,6 +199,8 @@ void Cbuf_InsertText (cmd_state_t *cmd, const char *text);
 void Cbuf_Execute (cmd_buf_t *cbuf);
 /*! Performs deferred commands and runs Cbuf_Execute, called by Host_Frame */
 void Cbuf_Frame (cmd_buf_t *cbuf);
+/// Clears all command buffers
+void Cbuf_Clear(cmd_buf_t *cbuf);
 
 //===========================================================================
 
diff --git a/host.c b/host.c
index 3e2c5f99075ab8e15934295b65bf84bde41d5c90..e7dd4a421b0d311a76bdd83051a632aff5b0f777 100644 (file)
--- a/host.c
+++ b/host.c
@@ -133,6 +133,9 @@ void Host_Error (const char *error, ...)
        if (cls.state == ca_dedicated)
                Sys_Error ("Host_Error: %s",hosterrorstring2);  // dedicated servers exit
 
+       // prevent an endless loop if the error was triggered by a command
+       Cbuf_Clear(cmd_local->cbuf);
+
        CL_Disconnect();
        cls.demonum = -1;