Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
552bc8aa
Commit
552bc8aa
authored
Jun 09, 2020
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Move the wait on address implementation to the Unix library.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
509ad75a
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
186 additions
and
220 deletions
+186
-220
loader.c
dlls/ntdll/loader.c
+0
-2
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+0
-1
sync.c
dlls/ntdll/sync.c
+3
-205
loader.c
dlls/ntdll/unix/loader.c
+3
-1
server.c
dlls/ntdll/unix/server.c
+3
-3
sync.c
dlls/ntdll/unix/sync.c
+168
-0
unix_private.h
dlls/ntdll/unix/unix_private.h
+5
-5
unixlib.h
dlls/ntdll/unixlib.h
+4
-3
No files found.
dlls/ntdll/loader.c
View file @
552bc8aa
...
...
@@ -4382,8 +4382,6 @@ void __wine_process_init(void)
init_user_process_params
(
info_size
);
params
=
peb
->
ProcessParameters
;
NtCreateKeyedEvent
(
&
keyed_event
,
GENERIC_READ
|
GENERIC_WRITE
,
NULL
,
0
);
/* retrieve current umask */
FILE_umask
=
umask
(
0777
);
umask
(
FILE_umask
);
...
...
dlls/ntdll/ntdll_misc.h
View file @
552bc8aa
...
...
@@ -213,7 +213,6 @@ static inline int get_unix_exit_code( NTSTATUS status )
}
extern
mode_t
FILE_umask
DECLSPEC_HIDDEN
;
extern
HANDLE
keyed_event
DECLSPEC_HIDDEN
;
extern
SYSTEM_CPU_INFORMATION
cpu_info
DECLSPEC_HIDDEN
;
#define HASH_STRING_ALGORITHM_DEFAULT 0
...
...
dlls/ntdll/sync.c
View file @
552bc8aa
...
...
@@ -63,66 +63,6 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
sync
);
HANDLE
keyed_event
=
NULL
;
static
const
LARGE_INTEGER
zero_timeout
;
#define TICKSPERSEC 10000000
#ifdef __linux__
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define FUTEX_WAIT_BITSET 9
#define FUTEX_WAKE_BITSET 10
static
int
futex_private
=
128
;
static
inline
int
futex_wait
(
const
int
*
addr
,
int
val
,
struct
timespec
*
timeout
)
{
return
syscall
(
__NR_futex
,
addr
,
FUTEX_WAIT
|
futex_private
,
val
,
timeout
,
0
,
0
);
}
static
inline
int
futex_wake
(
const
int
*
addr
,
int
val
)
{
return
syscall
(
__NR_futex
,
addr
,
FUTEX_WAKE
|
futex_private
,
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
)
{
futex_private
=
0
;
futex_wait
(
&
supported
,
10
,
NULL
);
}
supported
=
(
errno
!=
ENOSYS
);
}
return
supported
;
}
static
void
timespec_from_timeout
(
struct
timespec
*
timespec
,
const
LARGE_INTEGER
*
timeout
)
{
LARGE_INTEGER
now
;
timeout_t
diff
;
if
(
timeout
->
QuadPart
>
0
)
{
NtQuerySystemTime
(
&
now
);
diff
=
timeout
->
QuadPart
-
now
.
QuadPart
;
}
else
diff
=
-
timeout
->
QuadPart
;
timespec
->
tv_sec
=
diff
/
TICKSPERSEC
;
timespec
->
tv_nsec
=
(
diff
%
TICKSPERSEC
)
*
100
;
}
#endif
/* creates a struct security_descriptor and contained information in one contiguous piece of memory */
NTSTATUS
alloc_object_attributes
(
const
OBJECT_ATTRIBUTES
*
attr
,
struct
object_attributes
**
ret
,
data_size_t
*
ret_len
)
...
...
@@ -1558,145 +1498,13 @@ NTSTATUS WINAPI RtlSleepConditionVariableSRW( RTL_CONDITION_VARIABLE *variable,
return
status
;
}
static
RTL_CRITICAL_SECTION
addr_section
;
static
RTL_CRITICAL_SECTION_DEBUG
addr_section_debug
=
{
0
,
0
,
&
addr_section
,
{
&
addr_section_debug
.
ProcessLocksList
,
&
addr_section_debug
.
ProcessLocksList
},
0
,
0
,
{
(
DWORD_PTR
)(
__FILE__
": addr_section"
)
}
};
static
RTL_CRITICAL_SECTION
addr_section
=
{
&
addr_section_debug
,
-
1
,
0
,
0
,
0
,
0
};
static
BOOL
compare_addr
(
const
void
*
addr
,
const
void
*
cmp
,
SIZE_T
size
)
{
switch
(
size
)
{
case
1
:
return
(
*
(
const
UCHAR
*
)
addr
==
*
(
const
UCHAR
*
)
cmp
);
case
2
:
return
(
*
(
const
USHORT
*
)
addr
==
*
(
const
USHORT
*
)
cmp
);
case
4
:
return
(
*
(
const
ULONG
*
)
addr
==
*
(
const
ULONG
*
)
cmp
);
case
8
:
return
(
*
(
const
ULONG64
*
)
addr
==
*
(
const
ULONG64
*
)
cmp
);
}
return
FALSE
;
}
#ifdef __linux__
/* We can't map addresses to futex directly, because an application can wait on
* 8 bytes, and we can't pass all 8 as the compare value to futex(). Instead we
* map all addresses to a small fixed table of futexes. This may result in
* spurious wakes, but the application is already expected to handle those. */
static
int
addr_futex_table
[
256
];
static
inline
int
*
hash_addr
(
const
void
*
addr
)
{
ULONG_PTR
val
=
(
ULONG_PTR
)
addr
;
return
&
addr_futex_table
[(
val
>>
2
)
&
255
];
}
static
inline
NTSTATUS
fast_wait_addr
(
const
void
*
addr
,
const
void
*
cmp
,
SIZE_T
size
,
const
LARGE_INTEGER
*
timeout
)
{
int
*
futex
;
int
val
;
struct
timespec
timespec
;
int
ret
;
if
(
!
use_futexes
())
return
STATUS_NOT_IMPLEMENTED
;
futex
=
hash_addr
(
addr
);
/* We must read the previous value of the futex before checking the value
* of the address being waited on. That way, if we receive a wake between
* now and waiting on the futex, we know that val will have changed.
* Use an atomic load so that memory accesses are ordered between this read
* and the increment below. */
val
=
InterlockedCompareExchange
(
futex
,
0
,
0
);
if
(
!
compare_addr
(
addr
,
cmp
,
size
))
return
STATUS_SUCCESS
;
if
(
timeout
)
{
timespec_from_timeout
(
&
timespec
,
timeout
);
ret
=
futex_wait
(
futex
,
val
,
&
timespec
);
}
else
ret
=
futex_wait
(
futex
,
val
,
NULL
);
if
(
ret
==
-
1
&&
errno
==
ETIMEDOUT
)
return
STATUS_TIMEOUT
;
return
STATUS_SUCCESS
;
}
static
inline
NTSTATUS
fast_wake_addr
(
const
void
*
addr
)
{
int
*
futex
;
if
(
!
use_futexes
())
return
STATUS_NOT_IMPLEMENTED
;
futex
=
hash_addr
(
addr
);
InterlockedIncrement
(
futex
);
futex_wake
(
futex
,
INT_MAX
);
return
STATUS_SUCCESS
;
}
#else
static
inline
NTSTATUS
fast_wait_addr
(
const
void
*
addr
,
const
void
*
cmp
,
SIZE_T
size
,
const
LARGE_INTEGER
*
timeout
)
{
return
STATUS_NOT_IMPLEMENTED
;
}
static
inline
NTSTATUS
fast_wake_addr
(
const
void
*
addr
)
{
return
STATUS_NOT_IMPLEMENTED
;
}
#endif
/***********************************************************************
* RtlWaitOnAddress (NTDLL.@)
*/
NTSTATUS
WINAPI
RtlWaitOnAddress
(
const
void
*
addr
,
const
void
*
cmp
,
SIZE_T
size
,
const
LARGE_INTEGER
*
timeout
)
{
select_op_t
select_op
;
NTSTATUS
ret
;
timeout_t
abs_timeout
=
timeout
?
timeout
->
QuadPart
:
TIMEOUT_INFINITE
;
if
(
size
!=
1
&&
size
!=
2
&&
size
!=
4
&&
size
!=
8
)
return
STATUS_INVALID_PARAMETER
;
if
((
ret
=
fast_wait_addr
(
addr
,
cmp
,
size
,
timeout
))
!=
STATUS_NOT_IMPLEMENTED
)
return
ret
;
RtlEnterCriticalSection
(
&
addr_section
);
if
(
!
compare_addr
(
addr
,
cmp
,
size
))
{
RtlLeaveCriticalSection
(
&
addr_section
);
return
STATUS_SUCCESS
;
}
if
(
abs_timeout
<
0
)
{
LARGE_INTEGER
now
;
RtlQueryPerformanceCounter
(
&
now
);
abs_timeout
-=
now
.
QuadPart
;
}
select_op
.
keyed_event
.
op
=
SELECT_KEYED_EVENT_WAIT
;
select_op
.
keyed_event
.
handle
=
wine_server_obj_handle
(
keyed_event
);
select_op
.
keyed_event
.
key
=
wine_server_client_ptr
(
addr
);
return
unix_funcs
->
server_select
(
&
select_op
,
sizeof
(
select_op
.
keyed_event
),
SELECT_INTERRUPTIBLE
,
abs_timeout
,
NULL
,
&
addr_section
,
NULL
);
return
unix_funcs
->
RtlWaitOnAddress
(
addr
,
cmp
,
size
,
timeout
);
}
/***********************************************************************
...
...
@@ -1704,12 +1512,7 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size
*/
void
WINAPI
RtlWakeAddressAll
(
const
void
*
addr
)
{
if
(
fast_wake_addr
(
addr
)
!=
STATUS_NOT_IMPLEMENTED
)
return
;
RtlEnterCriticalSection
(
&
addr_section
);
while
(
NtReleaseKeyedEvent
(
0
,
addr
,
0
,
&
zero_timeout
)
==
STATUS_SUCCESS
)
{}
RtlLeaveCriticalSection
(
&
addr_section
);
return
unix_funcs
->
RtlWakeAddressAll
(
addr
);
}
/***********************************************************************
...
...
@@ -1717,10 +1520,5 @@ void WINAPI RtlWakeAddressAll( const void *addr )
*/
void
WINAPI
RtlWakeAddressSingle
(
const
void
*
addr
)
{
if
(
fast_wake_addr
(
addr
)
!=
STATUS_NOT_IMPLEMENTED
)
return
;
RtlEnterCriticalSection
(
&
addr_section
);
NtReleaseKeyedEvent
(
0
,
addr
,
0
,
&
zero_timeout
);
RtlLeaveCriticalSection
(
&
addr_section
);
return
unix_funcs
->
RtlWakeAddressSingle
(
addr
);
}
dlls/ntdll/unix/loader.c
View file @
552bc8aa
...
...
@@ -1046,6 +1046,9 @@ static struct unix_funcs unix_funcs =
NtWriteVirtualMemory
,
NtYieldExecution
,
DbgUiIssueRemoteBreakin
,
RtlWaitOnAddress
,
RtlWakeAddressAll
,
RtlWakeAddressSingle
,
fast_RtlTryAcquireSRWLockExclusive
,
fast_RtlAcquireSRWLockExclusive
,
fast_RtlTryAcquireSRWLockShared
,
...
...
@@ -1082,7 +1085,6 @@ static struct unix_funcs unix_funcs =
exit_process
,
get_thread_ldt_entry
,
wine_server_call
,
server_select
,
server_wait
,
server_send_fd
,
server_get_unix_fd
,
...
...
dlls/ntdll/unix/server.c
View file @
552bc8aa
...
...
@@ -602,9 +602,9 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result )
/***********************************************************************
* server_select
*/
unsigned
int
CDECL
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
)
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
)
{
unsigned
int
ret
;
int
cookie
;
...
...
dlls/ntdll/unix/sync.c
View file @
552bc8aa
...
...
@@ -71,6 +71,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(sync);
HANDLE
keyed_event
=
0
;
static
const
LARGE_INTEGER
zero_timeout
;
static
RTL_CRITICAL_SECTION
addr_section
;
static
RTL_CRITICAL_SECTION_DEBUG
addr_section_debug
=
{
0
,
0
,
&
addr_section
,
{
&
addr_section_debug
.
ProcessLocksList
,
&
addr_section_debug
.
ProcessLocksList
},
0
,
0
,
{
(
DWORD_PTR
)(
__FILE__
": addr_section"
)
}
};
static
RTL_CRITICAL_SECTION
addr_section
=
{
&
addr_section_debug
,
-
1
,
0
,
0
,
0
,
0
};
#ifdef __linux__
#define FUTEX_WAIT 0
...
...
@@ -147,6 +158,24 @@ static void timespec_from_timeout( struct timespec *timespec, const LARGE_INTEGE
#endif
static
BOOL
compare_addr
(
const
void
*
addr
,
const
void
*
cmp
,
SIZE_T
size
)
{
switch
(
size
)
{
case
1
:
return
(
*
(
const
UCHAR
*
)
addr
==
*
(
const
UCHAR
*
)
cmp
);
case
2
:
return
(
*
(
const
USHORT
*
)
addr
==
*
(
const
USHORT
*
)
cmp
);
case
4
:
return
(
*
(
const
ULONG
*
)
addr
==
*
(
const
ULONG
*
)
cmp
);
case
8
:
return
(
*
(
const
ULONG64
*
)
addr
==
*
(
const
ULONG64
*
)
cmp
);
}
return
FALSE
;
}
/* create a struct security_descriptor and contained information in one contiguous piece of memory */
NTSTATUS
alloc_object_attributes
(
const
OBJECT_ATTRIBUTES
*
attr
,
struct
object_attributes
**
ret
,
data_size_t
*
ret_len
)
...
...
@@ -1358,6 +1387,71 @@ NTSTATUS CDECL fast_RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable,
return
STATUS_SUCCESS
;
}
/* We can't map addresses to futex directly, because an application can wait on
* 8 bytes, and we can't pass all 8 as the compare value to futex(). Instead we
* map all addresses to a small fixed table of futexes. This may result in
* spurious wakes, but the application is already expected to handle those. */
static
int
addr_futex_table
[
256
];
static
inline
int
*
hash_addr
(
const
void
*
addr
)
{
ULONG_PTR
val
=
(
ULONG_PTR
)
addr
;
return
&
addr_futex_table
[(
val
>>
2
)
&
255
];
}
static
inline
NTSTATUS
fast_wait_addr
(
const
void
*
addr
,
const
void
*
cmp
,
SIZE_T
size
,
const
LARGE_INTEGER
*
timeout
)
{
int
*
futex
;
int
val
;
struct
timespec
timespec
;
int
ret
;
if
(
!
use_futexes
())
return
STATUS_NOT_IMPLEMENTED
;
futex
=
hash_addr
(
addr
);
/* We must read the previous value of the futex before checking the value
* of the address being waited on. That way, if we receive a wake between
* now and waiting on the futex, we know that val will have changed.
* Use an atomic load so that memory accesses are ordered between this read
* and the increment below. */
val
=
InterlockedCompareExchange
(
futex
,
0
,
0
);
if
(
!
compare_addr
(
addr
,
cmp
,
size
))
return
STATUS_SUCCESS
;
if
(
timeout
)
{
timespec_from_timeout
(
&
timespec
,
timeout
);
ret
=
futex_wait
(
futex
,
val
,
&
timespec
);
}
else
ret
=
futex_wait
(
futex
,
val
,
NULL
);
if
(
ret
==
-
1
&&
errno
==
ETIMEDOUT
)
return
STATUS_TIMEOUT
;
return
STATUS_SUCCESS
;
}
static
inline
NTSTATUS
fast_wake_addr
(
const
void
*
addr
)
{
int
*
futex
;
if
(
!
use_futexes
())
return
STATUS_NOT_IMPLEMENTED
;
futex
=
hash_addr
(
addr
);
InterlockedIncrement
(
futex
);
futex_wake
(
futex
,
INT_MAX
);
return
STATUS_SUCCESS
;
}
#else
NTSTATUS
CDECL
fast_RtlTryAcquireSRWLockExclusive
(
RTL_SRWLOCK
*
lock
)
...
...
@@ -1407,4 +1501,78 @@ NTSTATUS CDECL fast_RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable,
return
STATUS_NOT_IMPLEMENTED
;
}
static
inline
NTSTATUS
fast_wait_addr
(
const
void
*
addr
,
const
void
*
cmp
,
SIZE_T
size
,
const
LARGE_INTEGER
*
timeout
)
{
return
STATUS_NOT_IMPLEMENTED
;
}
static
inline
NTSTATUS
fast_wake_addr
(
const
void
*
addr
)
{
return
STATUS_NOT_IMPLEMENTED
;
}
#endif
/***********************************************************************
* RtlWaitOnAddress (NTDLL.@)
*/
NTSTATUS
WINAPI
RtlWaitOnAddress
(
const
void
*
addr
,
const
void
*
cmp
,
SIZE_T
size
,
const
LARGE_INTEGER
*
timeout
)
{
select_op_t
select_op
;
NTSTATUS
ret
;
timeout_t
abs_timeout
=
timeout
?
timeout
->
QuadPart
:
TIMEOUT_INFINITE
;
if
(
size
!=
1
&&
size
!=
2
&&
size
!=
4
&&
size
!=
8
)
return
STATUS_INVALID_PARAMETER
;
if
((
ret
=
fast_wait_addr
(
addr
,
cmp
,
size
,
timeout
))
!=
STATUS_NOT_IMPLEMENTED
)
return
ret
;
RtlEnterCriticalSection
(
&
addr_section
);
if
(
!
compare_addr
(
addr
,
cmp
,
size
))
{
RtlLeaveCriticalSection
(
&
addr_section
);
return
STATUS_SUCCESS
;
}
if
(
abs_timeout
<
0
)
{
LARGE_INTEGER
now
;
RtlQueryPerformanceCounter
(
&
now
);
abs_timeout
-=
now
.
QuadPart
;
}
select_op
.
keyed_event
.
op
=
SELECT_KEYED_EVENT_WAIT
;
select_op
.
keyed_event
.
handle
=
wine_server_obj_handle
(
keyed_event
);
select_op
.
keyed_event
.
key
=
wine_server_client_ptr
(
addr
);
return
server_select
(
&
select_op
,
sizeof
(
select_op
.
keyed_event
),
SELECT_INTERRUPTIBLE
,
abs_timeout
,
NULL
,
&
addr_section
,
NULL
);
}
/***********************************************************************
* RtlWakeAddressAll (NTDLL.@)
*/
void
WINAPI
RtlWakeAddressAll
(
const
void
*
addr
)
{
if
(
fast_wake_addr
(
addr
)
!=
STATUS_NOT_IMPLEMENTED
)
return
;
RtlEnterCriticalSection
(
&
addr_section
);
while
(
NtReleaseKeyedEvent
(
0
,
addr
,
0
,
&
zero_timeout
)
==
STATUS_SUCCESS
)
{}
RtlLeaveCriticalSection
(
&
addr_section
);
}
/***********************************************************************
* RtlWakeAddressSingle (NTDLL.@)
*/
void
WINAPI
RtlWakeAddressSingle
(
const
void
*
addr
)
{
if
(
fast_wake_addr
(
addr
)
!=
STATUS_NOT_IMPLEMENTED
)
return
;
RtlEnterCriticalSection
(
&
addr_section
);
NtReleaseKeyedEvent
(
0
,
addr
,
0
,
&
zero_timeout
);
RtlLeaveCriticalSection
(
&
addr_section
);
}
dlls/ntdll/unix/unix_private.h
View file @
552bc8aa
...
...
@@ -91,9 +91,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_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
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
;
...
...
@@ -128,6 +125,11 @@ extern unsigned int server_call_unlocked( void *req_ptr ) DECLSPEC_HIDDEN;
extern
void
server_enter_uninterrupted_section
(
RTL_CRITICAL_SECTION
*
cs
,
sigset_t
*
sigset
)
DECLSPEC_HIDDEN
;
extern
void
server_leave_uninterrupted_section
(
RTL_CRITICAL_SECTION
*
cs
,
sigset_t
*
sigset
)
DECLSPEC_HIDDEN
;
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_queue_process_apc
(
HANDLE
process
,
const
apc_call_t
*
call
,
apc_result_t
*
result
)
DECLSPEC_HIDDEN
;
extern
void
server_init_process
(
void
)
DECLSPEC_HIDDEN
;
extern
size_t
server_init_thread
(
void
*
entry_point
,
BOOL
*
suspend
)
DECLSPEC_HIDDEN
;
extern
int
server_pipe
(
int
fd
[
2
]
)
DECLSPEC_HIDDEN
;
...
...
@@ -139,8 +141,6 @@ extern void wait_suspend( CONTEXT *context ) DECLSPEC_HIDDEN;
extern
NTSTATUS
send_debug_event
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
set_thread_context
(
HANDLE
handle
,
const
context_t
*
context
,
BOOL
*
self
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
get_thread_context
(
HANDLE
handle
,
context_t
*
context
,
unsigned
int
flags
,
BOOL
*
self
)
DECLSPEC_HIDDEN
;
extern
unsigned
int
server_queue_process_apc
(
HANDLE
process
,
const
apc_call_t
*
call
,
apc_result_t
*
result
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
alloc_object_attributes
(
const
OBJECT_ATTRIBUTES
*
attr
,
struct
object_attributes
**
ret
,
data_size_t
*
ret_len
)
DECLSPEC_HIDDEN
;
...
...
dlls/ntdll/unixlib.h
View file @
552bc8aa
...
...
@@ -143,6 +143,10 @@ struct unix_funcs
/* other Win32 API functions */
NTSTATUS
(
WINAPI
*
DbgUiIssueRemoteBreakin
)(
HANDLE
process
);
NTSTATUS
(
WINAPI
*
RtlWaitOnAddress
)(
const
void
*
addr
,
const
void
*
cmp
,
SIZE_T
size
,
const
LARGE_INTEGER
*
timeout
);
void
(
WINAPI
*
RtlWakeAddressAll
)(
const
void
*
addr
);
void
(
WINAPI
*
RtlWakeAddressSingle
)(
const
void
*
addr
);
/* fast locks */
NTSTATUS
(
CDECL
*
fast_RtlTryAcquireSRWLockExclusive
)(
RTL_SRWLOCK
*
lock
);
...
...
@@ -199,9 +203,6 @@ struct unix_funcs
/* server functions */
unsigned
int
(
CDECL
*
server_call
)(
void
*
req_ptr
);
unsigned
int
(
CDECL
*
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
);
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
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment