ntdll: Move the critical section fallback code out of the Unix library.
This partially reverts commit ff19f21913
.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
647c54e539
commit
2c903e9e9b
|
@ -50,6 +50,44 @@ static BOOL crit_section_has_debuginfo(const RTL_CRITICAL_SECTION *crit)
|
|||
return crit->DebugInfo != NULL && crit->DebugInfo != no_debug_info_marker;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* get_semaphore
|
||||
*/
|
||||
static inline HANDLE get_semaphore( RTL_CRITICAL_SECTION *crit )
|
||||
{
|
||||
HANDLE ret = crit->LockSemaphore;
|
||||
if (!ret)
|
||||
{
|
||||
HANDLE sem;
|
||||
if (NtCreateSemaphore( &sem, SEMAPHORE_ALL_ACCESS, NULL, 0, 1 )) return 0;
|
||||
if (!(ret = InterlockedCompareExchangePointer( &crit->LockSemaphore, sem, 0 )))
|
||||
ret = sem;
|
||||
else
|
||||
NtClose(sem); /* somebody beat us to it */
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* wait_semaphore
|
||||
*/
|
||||
static inline NTSTATUS wait_semaphore( RTL_CRITICAL_SECTION *crit, int timeout )
|
||||
{
|
||||
NTSTATUS ret;
|
||||
|
||||
/* debug info is cleared by MakeCriticalSectionGlobal */
|
||||
if (!crit_section_has_debuginfo( crit ) ||
|
||||
((ret = unix_funcs->fast_RtlpWaitForCriticalSection( crit, timeout )) == STATUS_NOT_IMPLEMENTED))
|
||||
{
|
||||
HANDLE sem = get_semaphore( crit );
|
||||
LARGE_INTEGER time;
|
||||
|
||||
time.QuadPart = timeout * (LONGLONG)-10000000;
|
||||
ret = NtWaitForSingleObject( sem, FALSE, &time );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlInitializeCriticalSection (NTDLL.@)
|
||||
*
|
||||
|
@ -260,7 +298,7 @@ NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit )
|
|||
for (;;)
|
||||
{
|
||||
EXCEPTION_RECORD rec;
|
||||
NTSTATUS status = unix_funcs->fast_RtlpWaitForCriticalSection( crit, 5 );
|
||||
NTSTATUS status = wait_semaphore( crit, 5 );
|
||||
timeout -= 5;
|
||||
|
||||
if ( status == STATUS_TIMEOUT )
|
||||
|
@ -270,14 +308,14 @@ NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit )
|
|||
if (!name) name = "?";
|
||||
ERR( "section %p %s wait timed out in thread %04x, blocked by %04x, retrying (60 sec)\n",
|
||||
crit, debugstr_a(name), GetCurrentThreadId(), HandleToULong(crit->OwningThread) );
|
||||
status = unix_funcs->fast_RtlpWaitForCriticalSection( crit, 60 );
|
||||
status = wait_semaphore( crit, 60 );
|
||||
timeout -= 60;
|
||||
|
||||
if ( status == STATUS_TIMEOUT && TRACE_ON(relay) )
|
||||
{
|
||||
ERR( "section %p %s wait timed out in thread %04x, blocked by %04x, retrying (5 min)\n",
|
||||
crit, debugstr_a(name), GetCurrentThreadId(), HandleToULong(crit->OwningThread) );
|
||||
status = unix_funcs->fast_RtlpWaitForCriticalSection( crit, 300 );
|
||||
status = wait_semaphore( crit, 300 );
|
||||
timeout -= 300;
|
||||
}
|
||||
}
|
||||
|
@ -327,8 +365,15 @@ NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit )
|
|||
*/
|
||||
NTSTATUS WINAPI RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit )
|
||||
{
|
||||
NTSTATUS ret = unix_funcs->fast_RtlpUnWaitCriticalSection( crit );
|
||||
NTSTATUS ret;
|
||||
|
||||
/* debug info is cleared by MakeCriticalSectionGlobal */
|
||||
if (!crit_section_has_debuginfo( crit ) ||
|
||||
((ret = unix_funcs->fast_RtlpUnWaitCriticalSection( crit )) == STATUS_NOT_IMPLEMENTED))
|
||||
{
|
||||
HANDLE sem = get_semaphore( crit );
|
||||
ret = NtReleaseSemaphore( sem, 1, NULL );
|
||||
}
|
||||
if (ret) RtlRaiseStatus( ret );
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -2129,16 +2129,9 @@ NTSTATUS WINAPI NtQueryInformationAtom( RTL_ATOM atom, ATOM_INFORMATION_CLASS cl
|
|||
}
|
||||
|
||||
|
||||
static void *no_debug_info_marker = (void *)(ULONG_PTR)-1;
|
||||
|
||||
static BOOL crit_section_has_debuginfo(const RTL_CRITICAL_SECTION *crit)
|
||||
{
|
||||
return crit->DebugInfo != NULL && crit->DebugInfo != no_debug_info_marker;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
static inline NTSTATUS fast_critsection_wait( RTL_CRITICAL_SECTION *crit, int timeout )
|
||||
NTSTATUS CDECL fast_RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit, int timeout )
|
||||
{
|
||||
int val;
|
||||
struct timespec timespec;
|
||||
|
@ -2157,7 +2150,7 @@ static inline NTSTATUS fast_critsection_wait( RTL_CRITICAL_SECTION *crit, int ti
|
|||
return STATUS_WAIT_0;
|
||||
}
|
||||
|
||||
static inline NTSTATUS fast_critsection_wake( RTL_CRITICAL_SECTION *crit )
|
||||
NTSTATUS CDECL fast_RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit )
|
||||
{
|
||||
if (!use_futexes()) return STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
|
@ -2189,7 +2182,7 @@ static inline semaphore_t get_mach_semaphore( RTL_CRITICAL_SECTION *crit )
|
|||
return ret;
|
||||
}
|
||||
|
||||
static inline NTSTATUS fast_critsection_wait( RTL_CRITICAL_SECTION *crit, int timeout )
|
||||
NTSTATUS CDECL fast_RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit, int timeout )
|
||||
{
|
||||
mach_timespec_t timespec;
|
||||
semaphore_t sem = get_mach_semaphore( crit );
|
||||
|
@ -2212,7 +2205,7 @@ static inline NTSTATUS fast_critsection_wait( RTL_CRITICAL_SECTION *crit, int ti
|
|||
}
|
||||
}
|
||||
|
||||
static inline NTSTATUS fast_critsection_wake( RTL_CRITICAL_SECTION *crit )
|
||||
NTSTATUS CDECL fast_RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit )
|
||||
{
|
||||
semaphore_t sem = get_mach_semaphore( crit );
|
||||
semaphore_signal( sem );
|
||||
|
@ -2227,12 +2220,12 @@ NTSTATUS CDECL fast_RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit )
|
|||
|
||||
#else /* __APPLE__ */
|
||||
|
||||
static inline NTSTATUS fast_critsection_wait( RTL_CRITICAL_SECTION *crit, int timeout )
|
||||
NTSTATUS CDECL fast_RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit, int timeout )
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static inline NTSTATUS fast_critsection_wake( RTL_CRITICAL_SECTION *crit )
|
||||
NTSTATUS CDECL fast_RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit )
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
@ -2244,56 +2237,6 @@ NTSTATUS CDECL fast_RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit )
|
|||
|
||||
#endif
|
||||
|
||||
static inline HANDLE get_critsection_semaphore( RTL_CRITICAL_SECTION *crit )
|
||||
{
|
||||
HANDLE ret = crit->LockSemaphore;
|
||||
if (!ret)
|
||||
{
|
||||
HANDLE sem;
|
||||
if (NtCreateSemaphore( &sem, SEMAPHORE_ALL_ACCESS, NULL, 0, 1 )) return 0;
|
||||
if (!(ret = InterlockedCompareExchangePointer( &crit->LockSemaphore, sem, 0 )))
|
||||
ret = sem;
|
||||
else
|
||||
NtClose( sem ); /* somebody beat us to it */
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
NTSTATUS CDECL fast_RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit, int timeout )
|
||||
{
|
||||
NTSTATUS ret;
|
||||
|
||||
/* debug info is cleared by MakeCriticalSectionGlobal */
|
||||
if (!crit_section_has_debuginfo( crit ) ||
|
||||
((ret = fast_critsection_wait( crit, timeout )) == STATUS_NOT_IMPLEMENTED))
|
||||
{
|
||||
HANDLE sem = get_critsection_semaphore( crit );
|
||||
LARGE_INTEGER time;
|
||||
select_op_t select_op;
|
||||
|
||||
time.QuadPart = timeout * (LONGLONG)-10000000;
|
||||
select_op.wait.op = SELECT_WAIT;
|
||||
select_op.wait.handles[0] = wine_server_obj_handle( sem );
|
||||
ret = server_wait( &select_op, offsetof( select_op_t, wait.handles[1] ), 0, &time );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
NTSTATUS CDECL fast_RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit )
|
||||
{
|
||||
NTSTATUS ret;
|
||||
|
||||
/* debug info is cleared by MakeCriticalSectionGlobal */
|
||||
if (!crit_section_has_debuginfo( crit ) ||
|
||||
((ret = fast_critsection_wake( crit )) == STATUS_NOT_IMPLEMENTED))
|
||||
{
|
||||
HANDLE sem = get_critsection_semaphore( crit );
|
||||
ret = NtReleaseSemaphore( sem, 1, NULL );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
|
|
Loading…
Reference in New Issue