In
30c47b1aff3ac28359c469a40c44ee700c80e814 a bug in SVVM_reset_cmd was
revealed because that code never ran before that commit:
sometimes the server segfaulted at end of match because SVVM_reset_cmd
called QC code even though SVVM_reset_cmd would only be called by
PRVM_Prog_Reset after it had freed the tempstring memory... so if QC
created a tempstring, crash.
This commit refactors the SV VM shutdown to be consistent with the CL
and MENU shutdown by moving the QC SV_Shutdown() call into a separate
func that (optionally) resets the VM afterwards. As per
30c47b1aff3ac28359c469a40c44ee700c80e814 we MUST reset when stopping a
server to avoid crashes later, but we can still skip it when changing
map (like in previous versions).
Signed-off-by: bones_was_here <bones_was_here@xonotic.au>
return (host_isclient.integer && sv.active ? svs.maxclients : 0);
}
return (host_isclient.integer && sv.active ? svs.maxclients : 0);
}
+static void SV_VM_Shutdown(qbool prog_reset)
+{
+ prvm_prog_t *prog = SVVM_prog;
+
+ if(prog->loaded && PRVM_serverfunction(SV_Shutdown))
+ {
+ func_t s = PRVM_serverfunction(SV_Shutdown);
+ PRVM_serverglobalfloat(time) = sv.time;
+ PRVM_serverfunction(SV_Shutdown) = 0; // prevent it from getting called again
+ prog->ExecuteProgram(prog, s,"SV_Shutdown() required");
+ }
+ if (prog_reset)
+ PRVM_Prog_Reset(prog);
+}
+
/*
================
SV_SpawnServer
/*
================
SV_SpawnServer
- PRVM_Prog_Reset(prog); // calls graceful SVQC shutdown in SVVM_reset_cmd
// free q3 shaders so that any newly downloaded shaders will be active
Mod_FreeQ3Shaders();
// free q3 shaders so that any newly downloaded shaders will be active
Mod_FreeQ3Shaders();
*/
void SV_Shutdown(void)
{
*/
void SV_Shutdown(void)
{
- prvm_prog_t *prog = SVVM_prog;
int i;
SV_LockThreadMutex();
int i;
SV_LockThreadMutex();
if (host_client->active)
SV_DropClient(false, "Server shutting down"); // server shutdown
if (host_client->active)
SV_DropClient(false, "Server shutting down"); // server shutdown
- PRVM_Prog_Reset(prog); // calls graceful SVQC shutdown in SVVM_reset_cmd
NetConn_CloseServerPorts();
NetConn_CloseServerPorts();
void SVVM_reset_cmd(prvm_prog_t *prog)
{
World_End(&sv.world);
void SVVM_reset_cmd(prvm_prog_t *prog)
{
World_End(&sv.world);
-
- if(prog->loaded && PRVM_serverfunction(SV_Shutdown))
- {
- func_t s = PRVM_serverfunction(SV_Shutdown);
- PRVM_serverglobalfloat(time) = sv.time;
- PRVM_serverfunction(SV_Shutdown) = 0; // prevent it from getting called again
- prog->ExecuteProgram(prog, s,"SV_Shutdown() required");
- }
-