ntdll: Move the futex-based critical section implementation to the Unix library.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
552bc8aa47
commit
ff19f21913
|
@ -26,9 +26,6 @@
|
|||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_SYSCALL_H
|
||||
#include <sys/syscall.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
|
@ -56,187 +53,6 @@ static BOOL crit_section_has_debuginfo(const RTL_CRITICAL_SECTION *crit)
|
|||
return crit->DebugInfo != NULL && crit->DebugInfo != no_debug_info_marker;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
static int wait_op = 128; /*FUTEX_WAIT|FUTEX_PRIVATE_FLAG*/
|
||||
static int wake_op = 129; /*FUTEX_WAKE|FUTEX_PRIVATE_FLAG*/
|
||||
|
||||
static inline int futex_wait( int *addr, int val, struct timespec *timeout )
|
||||
{
|
||||
return syscall( __NR_futex, addr, wait_op, val, timeout, 0, 0 );
|
||||
}
|
||||
|
||||
static inline int futex_wake( int *addr, int val )
|
||||
{
|
||||
return syscall( __NR_futex, addr, wake_op, val, NULL, 0, 0 );
|
||||
}
|
||||
|
||||
static inline int use_futexes(void)
|
||||
{
|
||||
static int supported = -1;
|
||||
|
||||
if (supported == -1)
|
||||
{
|
||||
futex_wait( &supported, 10, NULL );
|
||||
if (errno == ENOSYS)
|
||||
{
|
||||
wait_op = 0; /*FUTEX_WAIT*/
|
||||
wake_op = 1; /*FUTEX_WAKE*/
|
||||
futex_wait( &supported, 10, NULL );
|
||||
}
|
||||
supported = (errno != ENOSYS);
|
||||
}
|
||||
return supported;
|
||||
}
|
||||
|
||||
static inline NTSTATUS fast_wait( RTL_CRITICAL_SECTION *crit, int timeout )
|
||||
{
|
||||
int val;
|
||||
struct timespec timespec;
|
||||
|
||||
if (!use_futexes()) return STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
timespec.tv_sec = timeout;
|
||||
timespec.tv_nsec = 0;
|
||||
while ((val = InterlockedCompareExchange( (int *)&crit->LockSemaphore, 0, 1 )) != 1)
|
||||
{
|
||||
/* note: this may wait longer than specified in case of signals or */
|
||||
/* multiple wake-ups, but that shouldn't be a problem */
|
||||
if (futex_wait( (int *)&crit->LockSemaphore, val, ×pec ) == -1 && errno == ETIMEDOUT)
|
||||
return STATUS_TIMEOUT;
|
||||
}
|
||||
return STATUS_WAIT_0;
|
||||
}
|
||||
|
||||
static inline NTSTATUS fast_wake( RTL_CRITICAL_SECTION *crit )
|
||||
{
|
||||
if (!use_futexes()) return STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
*(int *)&crit->LockSemaphore = 1;
|
||||
futex_wake( (int *)&crit->LockSemaphore, 1 );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline void close_semaphore( RTL_CRITICAL_SECTION *crit )
|
||||
{
|
||||
if (!use_futexes()) NtClose( crit->LockSemaphore );
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach/task.h>
|
||||
#include <mach/semaphore.h>
|
||||
|
||||
static inline semaphore_t get_mach_semaphore( RTL_CRITICAL_SECTION *crit )
|
||||
{
|
||||
semaphore_t ret = *(int *)&crit->LockSemaphore;
|
||||
if (!ret)
|
||||
{
|
||||
semaphore_t sem;
|
||||
if (semaphore_create( mach_task_self(), &sem, SYNC_POLICY_FIFO, 0 )) return 0;
|
||||
if (!(ret = InterlockedCompareExchange( (int *)&crit->LockSemaphore, sem, 0 )))
|
||||
ret = sem;
|
||||
else
|
||||
semaphore_destroy( mach_task_self(), sem ); /* somebody beat us to it */
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline NTSTATUS fast_wait( RTL_CRITICAL_SECTION *crit, int timeout )
|
||||
{
|
||||
mach_timespec_t timespec;
|
||||
semaphore_t sem = get_mach_semaphore( crit );
|
||||
|
||||
timespec.tv_sec = timeout;
|
||||
timespec.tv_nsec = 0;
|
||||
for (;;)
|
||||
{
|
||||
switch( semaphore_timedwait( sem, timespec ))
|
||||
{
|
||||
case KERN_SUCCESS:
|
||||
return STATUS_WAIT_0;
|
||||
case KERN_ABORTED:
|
||||
continue; /* got a signal, restart */
|
||||
case KERN_OPERATION_TIMED_OUT:
|
||||
return STATUS_TIMEOUT;
|
||||
default:
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline NTSTATUS fast_wake( RTL_CRITICAL_SECTION *crit )
|
||||
{
|
||||
semaphore_t sem = get_mach_semaphore( crit );
|
||||
semaphore_signal( sem );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline void close_semaphore( RTL_CRITICAL_SECTION *crit )
|
||||
{
|
||||
semaphore_destroy( mach_task_self(), *(int *)&crit->LockSemaphore );
|
||||
}
|
||||
|
||||
#else /* __APPLE__ */
|
||||
|
||||
static inline NTSTATUS fast_wait( RTL_CRITICAL_SECTION *crit, int timeout )
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static inline NTSTATUS fast_wake( RTL_CRITICAL_SECTION *crit )
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static inline void close_semaphore( RTL_CRITICAL_SECTION *crit )
|
||||
{
|
||||
NtClose( crit->LockSemaphore );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
* 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 = fast_wait( crit, timeout )) == STATUS_NOT_IMPLEMENTED))
|
||||
{
|
||||
HANDLE sem = get_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 = unix_funcs->server_wait( &select_op, offsetof( select_op_t, wait.handles[1] ), 0, &time );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlInitializeCriticalSection (NTDLL.@)
|
||||
*
|
||||
|
@ -402,7 +218,8 @@ NTSTATUS WINAPI RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit )
|
|||
RtlFreeHeap( GetProcessHeap(), 0, crit->DebugInfo );
|
||||
crit->DebugInfo = NULL;
|
||||
}
|
||||
close_semaphore( crit );
|
||||
if (unix_funcs->fast_RtlDeleteCriticalSection( crit ) == STATUS_NOT_IMPLEMENTED)
|
||||
NtClose( crit->LockSemaphore );
|
||||
}
|
||||
else NtClose( crit->LockSemaphore );
|
||||
crit->LockSemaphore = 0;
|
||||
|
@ -446,7 +263,7 @@ NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit )
|
|||
for (;;)
|
||||
{
|
||||
EXCEPTION_RECORD rec;
|
||||
NTSTATUS status = wait_semaphore( crit, 5 );
|
||||
NTSTATUS status = unix_funcs->fast_RtlpWaitForCriticalSection( crit, 5 );
|
||||
timeout -= 5;
|
||||
|
||||
if ( status == STATUS_TIMEOUT )
|
||||
|
@ -456,14 +273,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 = wait_semaphore( crit, 60 );
|
||||
status = unix_funcs->fast_RtlpWaitForCriticalSection( 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 = wait_semaphore( crit, 300 );
|
||||
status = unix_funcs->fast_RtlpWaitForCriticalSection( crit, 300 );
|
||||
timeout -= 300;
|
||||
}
|
||||
}
|
||||
|
@ -513,14 +330,8 @@ NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit )
|
|||
*/
|
||||
NTSTATUS WINAPI RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit )
|
||||
{
|
||||
NTSTATUS ret;
|
||||
NTSTATUS ret = unix_funcs->fast_RtlpUnWaitCriticalSection( crit );
|
||||
|
||||
/* debug info is cleared by MakeCriticalSectionGlobal */
|
||||
if (!crit_section_has_debuginfo( crit ) || ((ret = fast_wake( crit )) == STATUS_NOT_IMPLEMENTED))
|
||||
{
|
||||
HANDLE sem = get_semaphore( crit );
|
||||
ret = NtReleaseSemaphore( sem, 1, NULL );
|
||||
}
|
||||
if (ret) RtlRaiseStatus( ret );
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1049,6 +1049,9 @@ static struct unix_funcs unix_funcs =
|
|||
RtlWaitOnAddress,
|
||||
RtlWakeAddressAll,
|
||||
RtlWakeAddressSingle,
|
||||
fast_RtlpWaitForCriticalSection,
|
||||
fast_RtlpUnWaitCriticalSection,
|
||||
fast_RtlDeleteCriticalSection,
|
||||
fast_RtlTryAcquireSRWLockExclusive,
|
||||
fast_RtlAcquireSRWLockExclusive,
|
||||
fast_RtlTryAcquireSRWLockShared,
|
||||
|
@ -1085,7 +1088,6 @@ static struct unix_funcs unix_funcs =
|
|||
exit_process,
|
||||
get_thread_ldt_entry,
|
||||
wine_server_call,
|
||||
server_wait,
|
||||
server_send_fd,
|
||||
server_get_unix_fd,
|
||||
server_fd_to_handle,
|
||||
|
|
|
@ -681,8 +681,8 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
|
|||
/***********************************************************************
|
||||
* server_wait
|
||||
*/
|
||||
unsigned int CDECL server_wait( const select_op_t *select_op, data_size_t size, UINT flags,
|
||||
const LARGE_INTEGER *timeout )
|
||||
unsigned int server_wait( const select_op_t *select_op, data_size_t size, UINT flags,
|
||||
const LARGE_INTEGER *timeout )
|
||||
{
|
||||
timeout_t abs_timeout = timeout ? timeout->QuadPart : TIMEOUT_INFINITE;
|
||||
BOOL user_apc = FALSE;
|
||||
|
|
|
@ -55,6 +55,11 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#ifdef __APPLE__
|
||||
# include <mach/mach.h>
|
||||
# include <mach/task.h>
|
||||
# include <mach/semaphore.h>
|
||||
#endif
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
|
@ -1055,6 +1060,172 @@ NTSTATUS WINAPI NtOpenSection( HANDLE *handle, ACCESS_MASK access, const OBJECT_
|
|||
}
|
||||
|
||||
|
||||
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 )
|
||||
{
|
||||
int val;
|
||||
struct timespec timespec;
|
||||
|
||||
if (!use_futexes()) return STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
timespec.tv_sec = timeout;
|
||||
timespec.tv_nsec = 0;
|
||||
while ((val = InterlockedCompareExchange( (int *)&crit->LockSemaphore, 0, 1 )) != 1)
|
||||
{
|
||||
/* note: this may wait longer than specified in case of signals or */
|
||||
/* multiple wake-ups, but that shouldn't be a problem */
|
||||
if (futex_wait( (int *)&crit->LockSemaphore, val, ×pec ) == -1 && errno == ETIMEDOUT)
|
||||
return STATUS_TIMEOUT;
|
||||
}
|
||||
return STATUS_WAIT_0;
|
||||
}
|
||||
|
||||
static inline NTSTATUS fast_critsection_wake( RTL_CRITICAL_SECTION *crit )
|
||||
{
|
||||
if (!use_futexes()) return STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
*(int *)&crit->LockSemaphore = 1;
|
||||
futex_wake( (int *)&crit->LockSemaphore, 1 );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS CDECL fast_RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit )
|
||||
{
|
||||
if (!use_futexes()) return STATUS_NOT_IMPLEMENTED;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
static inline semaphore_t get_mach_semaphore( RTL_CRITICAL_SECTION *crit )
|
||||
{
|
||||
semaphore_t ret = *(int *)&crit->LockSemaphore;
|
||||
if (!ret)
|
||||
{
|
||||
semaphore_t sem;
|
||||
if (semaphore_create( mach_task_self(), &sem, SYNC_POLICY_FIFO, 0 )) return 0;
|
||||
if (!(ret = InterlockedCompareExchange( (int *)&crit->LockSemaphore, sem, 0 )))
|
||||
ret = sem;
|
||||
else
|
||||
semaphore_destroy( mach_task_self(), sem ); /* somebody beat us to it */
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline NTSTATUS fast_critsection_wait( RTL_CRITICAL_SECTION *crit, int timeout )
|
||||
{
|
||||
mach_timespec_t timespec;
|
||||
semaphore_t sem = get_mach_semaphore( crit );
|
||||
|
||||
timespec.tv_sec = timeout;
|
||||
timespec.tv_nsec = 0;
|
||||
for (;;)
|
||||
{
|
||||
switch( semaphore_timedwait( sem, timespec ))
|
||||
{
|
||||
case KERN_SUCCESS:
|
||||
return STATUS_WAIT_0;
|
||||
case KERN_ABORTED:
|
||||
continue; /* got a signal, restart */
|
||||
case KERN_OPERATION_TIMED_OUT:
|
||||
return STATUS_TIMEOUT;
|
||||
default:
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline NTSTATUS fast_critsection_wake( RTL_CRITICAL_SECTION *crit )
|
||||
{
|
||||
semaphore_t sem = get_mach_semaphore( crit );
|
||||
semaphore_signal( sem );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS CDECL fast_RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit )
|
||||
{
|
||||
semaphore_destroy( mach_task_self(), *(int *)&crit->LockSemaphore );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#else /* __APPLE__ */
|
||||
|
||||
static inline NTSTATUS fast_critsection_wait( RTL_CRITICAL_SECTION *crit, int timeout )
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static inline NTSTATUS fast_critsection_wake( RTL_CRITICAL_SECTION *crit )
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS CDECL fast_RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit )
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
#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__
|
||||
|
||||
/* Futex-based SRW lock implementation:
|
||||
|
|
|
@ -57,6 +57,9 @@ static inline struct ntdll_thread_data *ntdll_get_thread_data(void)
|
|||
NTSTATUS WINAPI KiUserExceptionDispatcher(EXCEPTION_RECORD*,CONTEXT*);
|
||||
void WINAPI LdrInitializeThunk(CONTEXT*,void**,ULONG_PTR,ULONG_PTR);
|
||||
|
||||
extern NTSTATUS CDECL fast_RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit, int timeout ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL fast_RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL fast_RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL fast_RtlTryAcquireSRWLockExclusive( RTL_SRWLOCK *lock ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL fast_RtlAcquireSRWLockExclusive( RTL_SRWLOCK *lock ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL fast_RtlTryAcquireSRWLockShared( RTL_SRWLOCK *lock ) DECLSPEC_HIDDEN;
|
||||
|
@ -91,8 +94,6 @@ extern void CDECL virtual_set_force_exec( BOOL enable ) DECLSPEC_HIDDEN;
|
|||
extern void CDECL virtual_release_address_space(void) DECLSPEC_HIDDEN;
|
||||
extern void CDECL virtual_set_large_address_space(void) DECLSPEC_HIDDEN;
|
||||
|
||||
extern unsigned int CDECL server_wait( const select_op_t *select_op, data_size_t size, UINT flags,
|
||||
const LARGE_INTEGER *timeout ) DECLSPEC_HIDDEN;
|
||||
extern void CDECL server_send_fd( int fd ) DECLSPEC_HIDDEN;
|
||||
extern int CDECL server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd,
|
||||
int *needs_close, enum server_fd_type *type,
|
||||
|
@ -128,6 +129,8 @@ extern void start_server( BOOL debug ) DECLSPEC_HIDDEN;
|
|||
extern unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT flags,
|
||||
timeout_t abs_timeout, CONTEXT *context, RTL_CRITICAL_SECTION *cs,
|
||||
user_apc_t *user_apc ) DECLSPEC_HIDDEN;
|
||||
extern unsigned int server_wait( const select_op_t *select_op, data_size_t size, UINT flags,
|
||||
const LARGE_INTEGER *timeout ) DECLSPEC_HIDDEN;
|
||||
extern unsigned int server_queue_process_apc( HANDLE process, const apc_call_t *call,
|
||||
apc_result_t *result ) DECLSPEC_HIDDEN;
|
||||
extern void server_init_process(void) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -28,7 +28,7 @@ struct ldt_copy;
|
|||
struct msghdr;
|
||||
|
||||
/* increment this when you change the function table */
|
||||
#define NTDLL_UNIXLIB_VERSION 36
|
||||
#define NTDLL_UNIXLIB_VERSION 37
|
||||
|
||||
struct unix_funcs
|
||||
{
|
||||
|
@ -149,6 +149,9 @@ struct unix_funcs
|
|||
void (WINAPI *RtlWakeAddressSingle)( const void *addr );
|
||||
|
||||
/* fast locks */
|
||||
NTSTATUS (CDECL *fast_RtlpWaitForCriticalSection)( RTL_CRITICAL_SECTION *crit, int timeout );
|
||||
NTSTATUS (CDECL *fast_RtlpUnWaitCriticalSection)( RTL_CRITICAL_SECTION *crit );
|
||||
NTSTATUS (CDECL *fast_RtlDeleteCriticalSection)( RTL_CRITICAL_SECTION *crit );
|
||||
NTSTATUS (CDECL *fast_RtlTryAcquireSRWLockExclusive)( RTL_SRWLOCK *lock );
|
||||
NTSTATUS (CDECL *fast_RtlAcquireSRWLockExclusive)( RTL_SRWLOCK *lock );
|
||||
NTSTATUS (CDECL *fast_RtlTryAcquireSRWLockShared)( RTL_SRWLOCK *lock );
|
||||
|
@ -203,8 +206,6 @@ struct unix_funcs
|
|||
|
||||
/* server functions */
|
||||
unsigned int (CDECL *server_call)( void *req_ptr );
|
||||
unsigned int (CDECL *server_wait)( const select_op_t *select_op, data_size_t size, UINT flags,
|
||||
const LARGE_INTEGER *timeout );
|
||||
void (CDECL *server_send_fd)( int fd );
|
||||
int (CDECL *server_get_unix_fd)( HANDLE handle, unsigned int wanted_access, int *unix_fd,
|
||||
int *needs_close, enum server_fd_type *type, unsigned int *options );
|
||||
|
|
Loading…
Reference in New Issue