From 151657a9f292a2269fba71f4786bcb988d64e47d Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Tue, 17 Apr 2012 15:59:14 -0400 Subject: [PATCH] Fix zombie plCrashHandler issues Win32 HACK: We wait on both the pfCrashCli handle and the crashed semaphore. This way, we can proceed to exit pfCrashSrv when the client process exits insanely. --- Sources/Plasma/CoreLib/hsThread.h | 14 +++++++++++++- .../FeatureLib/pfCrashHandler/plCrashSrv.cpp | 15 +++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/Sources/Plasma/CoreLib/hsThread.h b/Sources/Plasma/CoreLib/hsThread.h index e36d131b..c27e2118 100644 --- a/Sources/Plasma/CoreLib/hsThread.h +++ b/Sources/Plasma/CoreLib/hsThread.h @@ -115,7 +115,11 @@ class hsMutex { public: hsMutex(); virtual ~hsMutex(); - + +#ifdef HS_BUILD_FOR_WIN32 + HANDLE GetHandle() const { return fMutexH; } +#endif + void Lock(); hsBool TryLock(); void Unlock(); @@ -157,6 +161,10 @@ public: hsSemaphore(int initialValue=0, const char* name=nil); ~hsSemaphore(); +#ifdef HS_BUILD_FOR_WIN32 + HANDLE GetHandle() const { return fSemaH; } +#endif + hsBool TryWait(); hsBool Wait(hsMilliseconds timeToWait = kPosInfinity32); void Signal(); @@ -183,6 +191,10 @@ public: hsEvent(); ~hsEvent(); +#ifdef HS_BUILD_FOR_WIN32 + HANDLE GetHandle() const { return fEvent; } +#endif + hsBool Wait(hsMilliseconds timeToWait = kPosInfinity32); void Signal(); }; diff --git a/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashSrv.cpp b/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashSrv.cpp index 0efae16b..4b35a6c3 100644 --- a/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashSrv.cpp +++ b/Sources/Plasma/FeatureLib/pfCrashHandler/plCrashSrv.cpp @@ -108,10 +108,21 @@ void plCrashSrv::IHandleCrash() void plCrashSrv::HandleCrash() { - fCrashed->Wait(); // Wait for a crash +#ifdef HS_BUILD_FOR_WIN32 + if (!fLink) + FATAL("plCrashMemLink is nil!"); + + // In Win32 land we have to hackily handle the client process exiting, so we'll wait on both + // the crashed semaphore and the client process... + HANDLE hack[2] = { fLink->fClientProcess, fCrashed->GetHandle() }; + DWORD result = WaitForMultipleObjects(arrsize(hack), hack, FALSE, INFINITE); + hsAssert(result != WAIT_FAILED, "WaitForMultipleObjects failed"); +#else + fCrashed->Wait(); if (!fLink) FATAL("plCrashMemLink is nil!"); - else if (fLink->fCrashed) +#endif + if (fLink->fCrashed) IHandleCrash(); fHandled->Signal(); // Tell CrashCli we handled it }