Hi,
According to MSDN http://msdn.microsoft.com/en-us/library/ms682608(VS.85).aspx:
EnterCriticalSection can raise EXCEPTION_POSSIBLE_DEADLOCK if a wait operation on the critical section times out. The timeout interval is specified by the following registry value: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\CriticalSectionTimeout.
Currently, WIne doesn't implement this timeout feature, instead wine throws exception only for Wine internal locks after waiting for about 65 seconds, it is useful to check deadlock, see RtlpWaitForCriticalSection in dlls/ntdll/critsection.c
But this means a thread can't hold critical section longer than 65 seconds, otherwise app will crash. On some conditions, a thread does need hold critical section more than 65 seconds, for example: wine's implementation of GetAddress uses a critical section to protect non-reentrant gethostbyname() (well maybe need another gethostbyname_r() patch), see dlls/wininet/utility.c As you can see, gethostbyname() may take longtime when DNS setting is wrong or network is broken. If a multi-thread app calls GetAddress simultaneous in many threads, the app will crash.
I meet this problem when my network was broken, my app kept crash:
fixme:wininet:InternetSetOptionW INTERNET_OPTION_SEND/RECEIVE_TIMEOUT err:ntdll:RtlpWaitForCriticalSection section 0x7e44fa80 "utility.c: cs_gethostbyname" wait timed out in thread 0037, blocked by 003b, retrying (60 sec) fixme:msxml:DllCanUnloadNow wine: Critical section 7e44fa80 wait failed at address 0x7bc3c5bc (thread 0039), starting debugger... WineDbg starting on pid 0008 Unhandled exception: wait failed on critical section 0x7e44fa80 cs_gethostbyname err:seh:raise_exception Unhandled exception code c0000194 flags 0 addr 0x7bc3c5bc
So I suggest a feature that EnterCriticalSection throws exception for Wine internal locks only when debug is present.
Add the following code dlls/ntdll/critsection.c:
NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit ) { ........................... /* Throw exception only for Wine internal locks and debug is present */ if ((!crit->DebugInfo) || (!crit->DebugInfo->Spare[0])) continue; else if (!NtCurrentTeb()->Peb->BeingDebugged) continue; ^^^^^^^^^^^^^^^^^^ add ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
rec.ExceptionCode = STATUS_POSSIBLE_DEADLOCK; ............................ }
Any suggestion? Sorry If I'm not clean or missing something, thanks.