diff --git a/code/qcommon/common.c b/code/qcommon/common.c index 9482c04c..8fb492f7 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 a50da798..a9418824 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 919f09ce..c2efcd2b 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;