| 2188 | } |
| 2189 | |
| 2190 | static DWORD enterFastMutex(FAST_MUTEX* lpMutex, DWORD dwMilliseconds) |
| 2191 | { |
| 2192 | volatile FAST_MUTEX_SHARED_SECTION* lpSect = lpMutex->lpSharedInfo; |
| 2193 | |
| 2194 | while (true) |
| 2195 | { |
| 2196 | if (dwMilliseconds == 0) |
| 2197 | { |
| 2198 | if (!tryLockSharedSection(lpSect)) |
| 2199 | return WAIT_TIMEOUT; |
| 2200 | } |
| 2201 | else { |
| 2202 | lockSharedSection(lpSect, lpMutex->lSpinCount); |
| 2203 | } |
| 2204 | |
| 2205 | if (lpSect->lAvailable > 0) |
| 2206 | { |
| 2207 | lpSect->lAvailable--; |
| 2208 | lpSect->lOwnerPID = pid; |
| 2209 | #ifdef DEV_BUILD |
| 2210 | lpSect->lThreadId = GetCurrentThreadId(); |
| 2211 | #endif |
| 2212 | unlockSharedSection(lpSect); |
| 2213 | return WAIT_OBJECT_0; |
| 2214 | } |
| 2215 | |
| 2216 | if (dwMilliseconds == 0) |
| 2217 | { |
| 2218 | unlockSharedSection(lpSect); |
| 2219 | return WAIT_TIMEOUT; |
| 2220 | } |
| 2221 | |
| 2222 | InterlockedIncrement(FIX_TYPE(&lpSect->lThreadsWaiting)); |
| 2223 | unlockSharedSection(lpSect); |
| 2224 | |
| 2225 | // TODO actual timeout can be of any length |
| 2226 | const DWORD tm = (dwMilliseconds == INFINITE || dwMilliseconds > 5000) ? 5000 : dwMilliseconds; |
| 2227 | const DWORD dwResult = WaitForSingleObject(lpMutex->hEvent, tm); |
| 2228 | |
| 2229 | InterlockedDecrement(FIX_TYPE(&lpSect->lThreadsWaiting)); |
| 2230 | |
| 2231 | if (dwMilliseconds != INFINITE) |
| 2232 | dwMilliseconds -= tm; |
| 2233 | |
| 2234 | // if (dwResult != WAIT_OBJECT_0) |
| 2235 | // return dwResult; |
| 2236 | |
| 2237 | if (dwResult == WAIT_OBJECT_0) |
| 2238 | continue; |
| 2239 | if (dwResult == WAIT_ABANDONED) |
| 2240 | return dwResult; |
| 2241 | if (dwResult == WAIT_TIMEOUT && !dwMilliseconds) |
| 2242 | return dwResult; |
| 2243 | |
| 2244 | lockSharedSection(lpSect, lpMutex->lSpinCount); |
| 2245 | if (lpSect->lOwnerPID > 0 && !lpSect->lAvailable) |
| 2246 | { |
| 2247 | if (!ISC_check_process_existence(lpSect->lOwnerPID)) |
no test coverage detected