add watchdog timer to bsnes process to make sure they dont accumulate when the frontend terminates oddly

This commit is contained in:
zeromus 2014-06-17 22:03:08 +00:00
parent 0f1f22ae7e
commit 237045fde2
4 changed files with 56 additions and 1 deletions

View File

@ -34,6 +34,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
string InstanceName;
Process process;
System.Threading.EventWaitHandle watchdogEvent;
NamedPipeServerStream pipe;
BinaryWriter bwPipe;
BinaryReader brPipe;
@ -96,6 +97,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
pipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.None, 1024 * 1024, 1024);
//slim chance this might be useful sometimes:
//http://stackoverflow.com/questions/2590334/creating-a-cross-process-eventwaithandle
//create an event for the child process to monitor with a watchdog, to make sure it terminates when the emuhawk process terminates.
//NOTE: this is alarming! for some reason .net releases this event when it gets finalized, instead of when i (dont) dispose it.
bool createdNew;
watchdogEvent = new System.Threading.EventWaitHandle(false, System.Threading.EventResetMode.AutoReset, InstanceName + "-event", out createdNew);
process = new Process();
process.StartInfo.WorkingDirectory = Path.GetDirectoryName(exePath);
process.StartInfo.FileName = exePath;
@ -134,6 +142,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
public void Dispose()
{
watchdogEvent.Dispose();
process.Kill();
process.Dispose();
process = null;

View File

@ -342,10 +342,51 @@ public:
}
}; //class IPCRingBuffer
class Watchdog
{
public:
void Start(const char* _eventName)
{
HANDLE thread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)&ThreadProc, this, 0, NULL);
SetThreadPriority(thread,THREAD_PRIORITY_LOWEST);
eventName = _eventName;
}
private:
std::string eventName;
static DWORD ThreadProc(LPVOID lpParam)
{
Watchdog* w = (Watchdog*)lpParam;
for(;;)
{
//only check once per second
Sleep(1000);
//try opening the handle. if its gone, the process is gone
HANDLE hEvent = OpenEvent(SYNCHRONIZE | EVENT_ALL_ACCESS, FALSE, w->eventName.c_str());
//printf("event handle: %08X (%d)\n",hEvent,hEvent?0:GetLastError()); //debugging
//handle was gone, terminate process
if(hEvent == 0)
{
TerminateProcess(INVALID_HANDLE_VALUE,0);
}
CloseHandle(hEvent);
}
}
}; //class Watchdog
static bool bufio = false;
static IPCRingBuffer *rbuf = NULL, *wbuf = NULL;
HANDLE hPipe, hMapFile;
Watchdog s_Watchdog;
HANDLE hPipe, hMapFile, hEvent;
void* hMapFilePtr;
static bool running = false;
@ -1199,7 +1240,9 @@ int xmain(int argc, char** argv)
}
char pipename[256];
char eventname[256];
sprintf(pipename, "\\\\.\\Pipe\\%s",argv[1]);
sprintf(eventname, "%s-event",argv[1]);
if(!strncmp(argv[1],"console",7))
{
@ -1207,6 +1250,9 @@ int xmain(int argc, char** argv)
}
printf("pipe: %s\n",pipename);
printf("event: %s\n",eventname);
s_Watchdog.Start(eventname);
hPipe = CreateFile(pipename, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);