From: <hv...@us...> - 2011-02-02 12:10:18
|
Revision: 52272 http://firebird.svn.sourceforge.net/firebird/?rev=52272&view=rev Author: hvlad Date: 2011-02-02 12:10:12 +0000 (Wed, 02 Feb 2011) Log Message: ----------- Fixed bug CORE-3326 : Fast mutex could be left in locked state by dead process Modified Paths: -------------- firebird/branches/B2_5_Release/src/jrd/isc.h firebird/branches/B2_5_Release/src/jrd/isc_sync.cpp Modified: firebird/branches/B2_5_Release/src/jrd/isc.h =================================================================== --- firebird/branches/B2_5_Release/src/jrd/isc.h 2011-02-02 11:56:48 UTC (rev 52271) +++ firebird/branches/B2_5_Release/src/jrd/isc.h 2011-02-02 12:10:12 UTC (rev 52272) @@ -122,6 +122,7 @@ SLONG lSpinLock; SLONG lThreadsWaiting; SLONG lAvailable; + SLONG lOwnerPID; #ifdef _DEBUG DWORD dwThreadId; #endif Modified: firebird/branches/B2_5_Release/src/jrd/isc_sync.cpp =================================================================== --- firebird/branches/B2_5_Release/src/jrd/isc_sync.cpp 2011-02-02 11:56:48 UTC (rev 52271) +++ firebird/branches/B2_5_Release/src/jrd/isc_sync.cpp 2011-02-02 12:10:12 UTC (rev 52272) @@ -2813,6 +2813,7 @@ static const int DEFAULT_INTERLOCKED_SPIN_COUNT = 0; static const int DEFAULT_INTERLOCKED_SPIN_COUNT_SMP = 200; +static SLONG pid = 0; typedef WINBASEAPI BOOL (WINAPI *pfnSwitchToThread) (); static inline BOOL switchToThread() @@ -2904,6 +2905,7 @@ #ifdef _DEBUG lpSect->dwThreadId = GetCurrentThreadId(); #endif + lpSect->lOwnerPID = pid; unlockSharedSection(lpSect); return WAIT_OBJECT_0; } @@ -2922,11 +2924,36 @@ unlockSharedSection(lpSect); // TODO actual timeout can be of any length - const DWORD dwResult = WaitForSingleObject(lpMutex->hEvent, dwMilliseconds); + const DWORD tm = (dwMilliseconds == INFINITE) ? 5000 : + ((dwMilliseconds > 5000) ? 5000 : dwMilliseconds); + const DWORD dwResult = WaitForSingleObject(lpMutex->hEvent, tm); + InterlockedDecrement(FIX_TYPE(&lpSect->lThreadsWaiting)); - if (dwResult != WAIT_OBJECT_0) + if (dwMilliseconds != INFINITE) + dwMilliseconds -= tm; + +// if (dwResult != WAIT_OBJECT_0) +// return dwResult; + + if (dwResult == WAIT_ABANDONED) return dwResult; + if (dwResult == WAIT_TIMEOUT && !dwMilliseconds) + return dwResult; + + lockSharedSection(lpSect, lpMutex->lSpinCount); + if (lpSect->lOwnerPID > 0 && !lpSect->lAvailable) + { + if (!ISC_check_process_existence(lpSect->lOwnerPID)) + { +#ifdef DEBUG + gds__log("enterFastMutex: dead process detected, pid = %d", lpSect->lOwnerPID); +#endif + lpSect->lOwnerPID = 0; + lpSect->lAvailable++; + } + } + unlockSharedSection(lpSect); } } @@ -2944,6 +2971,7 @@ lpSect->lAvailable++; if (lpSect->lThreadsWaiting) SetEvent(lpMutex->hEvent); + lpSect->lOwnerPID = -pid; unlockSharedSection(lpSect); return true; @@ -2970,6 +2998,9 @@ static bool initializeFastMutex(FAST_MUTEX* lpMutex, LPSECURITY_ATTRIBUTES lpAttributes, BOOL bInitialState, LPCSTR lpName) { + if (pid == 0) + pid = GetCurrentProcessId(); + LPCSTR name = lpName; if (strlen(lpName) + strlen(FAST_MUTEX_EVT_NAME) - 2 >= MAXPATHLEN) @@ -3018,6 +3049,7 @@ lpMutex->lpSharedInfo->lSpinLock = 0; lpMutex->lpSharedInfo->lThreadsWaiting = 0; lpMutex->lpSharedInfo->lAvailable = bInitialState ? 0 : 1; + lpMutex->lpSharedInfo->lOwnerPID = bInitialState ? pid : 0; InterlockedExchange(FIX_TYPE(&lpMutex->lpSharedInfo->fInitialized), 1); } else This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |