From 9826eeddf3b87b7da83e0ef6c6a1e6d7784267e0 Mon Sep 17 00:00:00 2001
From: ludwig <ludwig@edf5b092-35ff-0310-97b2-ce42778d08ea>
Date: Sun, 6 Apr 2008 12:59:35 +0000
Subject: set flag to allow forced unload of a running VM

required to prevent a client from exiting if the server disconnects (bug 3585)

git-svn-id: svn://svn.icculus.org/quake3/trunk@1300 edf5b092-35ff-0310-97b2-ce42778d08ea
---
 code/qcommon/common.c  |  2 ++
 code/qcommon/qcommon.h |  2 ++
 code/qcommon/vm.c      | 19 +++++++++++++++++--
 3 files changed, 21 insertions(+), 2 deletions(-)

(limited to 'code')

diff --git a/code/qcommon/common.c b/code/qcommon/common.c
index 9482c04..8fb492f 100644
--- a/code/qcommon/common.c
+++ b/code/qcommon/common.c
@@ -277,7 +277,9 @@ void QDECL Com_Error( int code, const char *fmt, ... ) {
 
 	if (code == ERR_DISCONNECT || code == ERR_SERVERDISCONNECT) {
 		CL_Disconnect( qtrue );
+		VM_Forced_Unload_Start();
 		CL_FlushMemory( );
+		VM_Forced_Unload_Done();
 		// make sure we can get at our local stuff
 		FS_PureServerSetLoadedPaks("", "");
 		com_errorEntered = qfalse;
diff --git a/code/qcommon/qcommon.h b/code/qcommon/qcommon.h
index a50da79..a941882 100644
--- a/code/qcommon/qcommon.h
+++ b/code/qcommon/qcommon.h
@@ -325,6 +325,8 @@ vm_t	*VM_Create( const char *module, intptr_t (*systemCalls)(intptr_t *),
 
 void	VM_Free( vm_t *vm );
 void	VM_Clear(void);
+void	VM_Forced_Unload_Start(void);
+void	VM_Forced_Unload_Done(void);
 vm_t	*VM_Restart( vm_t *vm );
 
 intptr_t		QDECL VM_Call( vm_t *vm, int callNum, ... );
diff --git a/code/qcommon/vm.c b/code/qcommon/vm.c
index 919f09c..c2efcd2 100644
--- a/code/qcommon/vm.c
+++ b/code/qcommon/vm.c
@@ -40,6 +40,9 @@ vm_t	*currentVM = NULL;
 vm_t	*lastVM    = NULL;
 int		vm_debugLevel;
 
+// used by Com_Error to get rid of running vm's before longjmp
+static int forced_unload;
+
 #define	MAX_VM		3
 vm_t	vmTable[MAX_VM];
 
@@ -613,8 +616,12 @@ void VM_Free( vm_t *vm ) {
 	}
 
 	if(vm->callLevel) {
-		Com_Error( ERR_FATAL, "VM_Free(%s) on running vm", vm->name );
-		return;
+		if(!forced_unload) {
+			Com_Error( ERR_FATAL, "VM_Free(%s) on running vm", vm->name );
+			return;
+		} else {
+			Com_Printf( "forcefully unloading %s vm\n", vm->name );
+		}
 	}
 
 	if(vm->destroy)
@@ -648,6 +655,14 @@ void VM_Clear(void) {
 	}
 }
 
+void VM_Forced_Unload_Start(void) {
+	forced_unload = 1;
+}
+
+void VM_Forced_Unload_Done(void) {
+	forced_unload = 0;
+}
+
 void *VM_ArgPtr( intptr_t intValue ) {
 	if ( !intValue ) {
 		return NULL;
-- 
cgit v1.2.3