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
321d26cb
Commit
321d26cb
authored
Apr 06, 2020
by
Piotr Caban
Committed by
Alexandre Julliard
Apr 09, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Use correct clock in select.
Signed-off-by:
Piotr Caban
<
piotr@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
6d2d3595
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
62 additions
and
45 deletions
+62
-45
server.c
dlls/ntdll/server.c
+9
-2
sync.c
dlls/ntdll/sync.c
+9
-2
server_protocol.h
include/wine/server_protocol.h
+3
-4
protocol.def
server/protocol.def
+1
-2
request.h
server/request.h
+4
-4
thread.c
server/thread.c
+27
-28
trace.c
server/trace.c
+8
-3
make_requests
tools/make_requests
+1
-0
No files found.
dlls/ntdll/server.c
View file @
321d26cb
...
...
@@ -600,11 +600,19 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
obj_handle_t
apc_handle
=
0
;
apc_call_t
call
;
apc_result_t
result
;
timeout
_t
abs_timeout
=
timeout
?
timeout
->
QuadPart
:
TIMEOUT_INFINITE
;
abstime
_t
abs_timeout
=
timeout
?
timeout
->
QuadPart
:
TIMEOUT_INFINITE
;
sigset_t
old_set
;
memset
(
&
result
,
0
,
sizeof
(
result
)
);
if
(
abs_timeout
<
0
)
{
LARGE_INTEGER
now
;
RtlQueryPerformanceCounter
(
&
now
);
abs_timeout
-=
now
.
QuadPart
;
}
do
{
pthread_sigmask
(
SIG_BLOCK
,
&
server_block_set
,
&
old_set
);
...
...
@@ -619,7 +627,6 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
wine_server_add_data
(
req
,
&
result
,
sizeof
(
result
)
);
wine_server_add_data
(
req
,
select_op
,
size
);
ret
=
server_call_unlocked
(
req
);
abs_timeout
=
reply
->
timeout
;
apc_handle
=
reply
->
apc_handle
;
call
=
reply
->
call
;
}
...
...
dlls/ntdll/sync.c
View file @
321d26cb
...
...
@@ -2463,7 +2463,7 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size
obj_handle_t
apc_handle
=
0
;
apc_call_t
call
;
apc_result_t
result
;
timeout
_t
abs_timeout
=
timeout
?
timeout
->
QuadPart
:
TIMEOUT_INFINITE
;
abstime
_t
abs_timeout
=
timeout
?
timeout
->
QuadPart
:
TIMEOUT_INFINITE
;
sigset_t
old_set
;
if
(
size
!=
1
&&
size
!=
2
&&
size
!=
4
&&
size
!=
8
)
...
...
@@ -2478,6 +2478,14 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size
memset
(
&
result
,
0
,
sizeof
(
result
)
);
if
(
abs_timeout
<
0
)
{
LARGE_INTEGER
now
;
RtlQueryPerformanceCounter
(
&
now
);
abs_timeout
-=
now
.
QuadPart
;
}
do
{
RtlEnterCriticalSection
(
&
addr_section
);
...
...
@@ -2499,7 +2507,6 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size
wine_server_add_data
(
req
,
&
result
,
sizeof
(
result
)
);
wine_server_add_data
(
req
,
&
select_op
,
sizeof
(
select_op
.
keyed_event
)
);
ret
=
server_call_unlocked
(
req
);
abs_timeout
=
reply
->
timeout
;
apc_handle
=
reply
->
apc_handle
;
call
=
reply
->
call
;
}
...
...
include/wine/server_protocol.h
View file @
321d26cb
...
...
@@ -1250,7 +1250,7 @@ struct select_request
struct
request_header
__header
;
int
flags
;
client_ptr_t
cookie
;
timeout
_t
timeout
;
abstime
_t
timeout
;
obj_handle_t
prev_apc
;
/* VARARG(result,apc_result); */
/* VARARG(data,select_op); */
...
...
@@ -1259,10 +1259,9 @@ struct select_request
struct
select_reply
{
struct
reply_header
__header
;
timeout_t
timeout
;
apc_call_t
call
;
obj_handle_t
apc_handle
;
char
__pad_
60
[
4
];
char
__pad_
52
[
4
];
};
#define SELECT_ALERTABLE 1
#define SELECT_INTERRUPTIBLE 2
...
...
@@ -6711,7 +6710,7 @@ union generic_reply
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 59
6
#define SERVER_PROTOCOL_VERSION 59
7
/* ### protocol_version end ### */
...
...
server/protocol.def
View file @
321d26cb
...
...
@@ -1099,12 +1099,11 @@ struct rawinput_device
@REQ(select)
int flags; /* wait flags (see below) */
client_ptr_t cookie; /* magic cookie to return to client */
timeout
_t timeout; /* timeout */
abstime
_t timeout; /* timeout */
obj_handle_t prev_apc; /* handle to previous APC */
VARARG(result,apc_result); /* result of previous APC */
VARARG(data,select_op); /* operation-specific data */
@REPLY
timeout_t timeout; /* timeout converted to absolute */
apc_call_t call; /* APC call arguments */
obj_handle_t apc_handle; /* handle to next APC */
@END
...
...
server/request.h
View file @
321d26cb
...
...
@@ -721,6 +721,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(
req_handler
)
req_resume_process
,
};
C_ASSERT
(
sizeof
(
abstime_t
)
==
8
);
C_ASSERT
(
sizeof
(
affinity_t
)
==
8
);
C_ASSERT
(
sizeof
(
apc_call_t
)
==
40
);
C_ASSERT
(
sizeof
(
apc_param_t
)
==
8
);
...
...
@@ -939,10 +940,9 @@ C_ASSERT( FIELD_OFFSET(struct select_request, cookie) == 16 );
C_ASSERT
(
FIELD_OFFSET
(
struct
select_request
,
timeout
)
==
24
);
C_ASSERT
(
FIELD_OFFSET
(
struct
select_request
,
prev_apc
)
==
32
);
C_ASSERT
(
sizeof
(
struct
select_request
)
==
40
);
C_ASSERT
(
FIELD_OFFSET
(
struct
select_reply
,
timeout
)
==
8
);
C_ASSERT
(
FIELD_OFFSET
(
struct
select_reply
,
call
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
select_reply
,
apc_handle
)
==
56
);
C_ASSERT
(
sizeof
(
struct
select_reply
)
==
64
);
C_ASSERT
(
FIELD_OFFSET
(
struct
select_reply
,
call
)
==
8
);
C_ASSERT
(
FIELD_OFFSET
(
struct
select_reply
,
apc_handle
)
==
48
);
C_ASSERT
(
sizeof
(
struct
select_reply
)
==
56
);
C_ASSERT
(
FIELD_OFFSET
(
struct
create_event_request
,
access
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
create_event_request
,
manual_reset
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
create_event_request
,
initial_state
)
==
20
);
...
...
server/thread.c
View file @
321d26cb
...
...
@@ -79,7 +79,7 @@ struct thread_wait
enum
select_op
select
;
client_ptr_t
key
;
/* wait key for keyed events */
client_ptr_t
cookie
;
/* magic cookie to return to client */
timeout_t
timeout
;
abstime_t
when
;
struct
timeout_user
*
user
;
struct
wait_queue_entry
queues
[
1
];
};
...
...
@@ -687,7 +687,7 @@ static unsigned int end_wait( struct thread *thread, unsigned int status )
/* build the thread wait structure */
static
int
wait_on
(
const
select_op_t
*
select_op
,
unsigned
int
count
,
struct
object
*
objects
[],
int
flags
,
timeout_t
timeout
)
int
flags
,
abstime_t
when
)
{
struct
thread_wait
*
wait
;
struct
wait_queue_entry
*
entry
;
...
...
@@ -701,7 +701,7 @@ static int wait_on( const select_op_t *select_op, unsigned int count, struct obj
wait
->
select
=
select_op
->
op
;
wait
->
cookie
=
0
;
wait
->
user
=
NULL
;
wait
->
timeout
=
timeout
;
wait
->
when
=
when
;
wait
->
abandoned
=
0
;
current
->
wait
=
wait
;
...
...
@@ -720,7 +720,7 @@ static int wait_on( const select_op_t *select_op, unsigned int count, struct obj
}
static
int
wait_on_handles
(
const
select_op_t
*
select_op
,
unsigned
int
count
,
const
obj_handle_t
*
handles
,
int
flags
,
timeout_t
timeout
)
int
flags
,
abstime_t
when
)
{
struct
object
*
objects
[
MAXIMUM_WAIT_OBJECTS
];
unsigned
int
i
;
...
...
@@ -732,7 +732,7 @@ static int wait_on_handles( const select_op_t *select_op, unsigned int count, co
if
(
!
(
objects
[
i
]
=
get_handle_obj
(
current
->
process
,
handles
[
i
],
SYNCHRONIZE
,
NULL
)))
break
;
if
(
i
==
count
)
ret
=
wait_on
(
select_op
,
count
,
objects
,
flags
,
timeout
);
if
(
i
==
count
)
ret
=
wait_on
(
select_op
,
count
,
objects
,
flags
,
when
);
while
(
i
>
0
)
release_object
(
objects
[
--
i
]
);
return
ret
;
...
...
@@ -769,7 +769,8 @@ static int check_wait( struct thread *thread )
}
if
((
wait
->
flags
&
SELECT_ALERTABLE
)
&&
!
list_empty
(
&
thread
->
user_apc
))
return
STATUS_USER_APC
;
if
(
wait
->
timeout
<=
current_time
)
return
STATUS_TIMEOUT
;
if
(
wait
->
when
>=
0
&&
wait
->
when
<=
current_time
)
return
STATUS_TIMEOUT
;
if
(
wait
->
when
<
0
&&
-
wait
->
when
<=
monotonic_time
)
return
STATUS_TIMEOUT
;
return
-
1
;
}
...
...
@@ -875,19 +876,17 @@ static int signal_object( obj_handle_t handle )
}
/* select on a list of handles */
static
timeout_t
select_on
(
const
select_op_t
*
select_op
,
data_size_t
op_size
,
client_ptr_t
cookie
,
int
flags
,
timeout_t
timeout
)
static
void
select_on
(
const
select_op_t
*
select_op
,
data_size_t
op_size
,
client_ptr_t
cookie
,
int
flags
,
abstime_t
when
)
{
int
ret
;
unsigned
int
count
;
struct
object
*
object
;
if
(
timeout
<=
0
)
timeout
=
current_time
-
timeout
;
switch
(
select_op
->
op
)
{
case
SELECT_NONE
:
if
(
!
wait_on
(
select_op
,
0
,
NULL
,
flags
,
timeout
))
return
timeout
;
if
(
!
wait_on
(
select_op
,
0
,
NULL
,
flags
,
when
))
return
;
break
;
case
SELECT_WAIT
:
...
...
@@ -896,24 +895,24 @@ static timeout_t select_on( const select_op_t *select_op, data_size_t op_size, c
if
(
op_size
<
offsetof
(
select_op_t
,
wait
.
handles
)
||
count
>
MAXIMUM_WAIT_OBJECTS
)
{
set_error
(
STATUS_INVALID_PARAMETER
);
return
0
;
return
;
}
if
(
!
wait_on_handles
(
select_op
,
count
,
select_op
->
wait
.
handles
,
flags
,
timeout
))
return
timeout
;
if
(
!
wait_on_handles
(
select_op
,
count
,
select_op
->
wait
.
handles
,
flags
,
when
))
return
;
break
;
case
SELECT_SIGNAL_AND_WAIT
:
if
(
!
wait_on_handles
(
select_op
,
1
,
&
select_op
->
signal_and_wait
.
wait
,
flags
,
timeout
))
return
timeout
;
if
(
!
wait_on_handles
(
select_op
,
1
,
&
select_op
->
signal_and_wait
.
wait
,
flags
,
when
))
return
;
if
(
select_op
->
signal_and_wait
.
signal
)
{
if
(
!
signal_object
(
select_op
->
signal_and_wait
.
signal
))
{
end_wait
(
current
,
get_error
()
);
return
timeout
;
return
;
}
/* check if we woke ourselves up */
if
(
!
current
->
wait
)
return
timeout
;
if
(
!
current
->
wait
)
return
;
}
break
;
...
...
@@ -921,38 +920,38 @@ static timeout_t select_on( const select_op_t *select_op, data_size_t op_size, c
case
SELECT_KEYED_EVENT_RELEASE
:
object
=
(
struct
object
*
)
get_keyed_event_obj
(
current
->
process
,
select_op
->
keyed_event
.
handle
,
select_op
->
op
==
SELECT_KEYED_EVENT_WAIT
?
KEYEDEVENT_WAIT
:
KEYEDEVENT_WAKE
);
if
(
!
object
)
return
timeout
;
ret
=
wait_on
(
select_op
,
1
,
&
object
,
flags
,
timeout
);
if
(
!
object
)
return
;
ret
=
wait_on
(
select_op
,
1
,
&
object
,
flags
,
when
);
release_object
(
object
);
if
(
!
ret
)
return
timeout
;
if
(
!
ret
)
return
;
current
->
wait
->
key
=
select_op
->
keyed_event
.
key
;
break
;
default:
set_error
(
STATUS_INVALID_PARAMETER
);
return
0
;
return
;
}
if
((
ret
=
check_wait
(
current
))
!=
-
1
)
{
/* condition is already satisfied */
set_error
(
end_wait
(
current
,
ret
));
return
timeout
;
return
;
}
/* now we need to wait */
if
(
current
->
wait
->
timeout
!=
TIMEOUT_INFINITE
)
if
(
current
->
wait
->
when
!=
TIMEOUT_INFINITE
)
{
if
(
!
(
current
->
wait
->
user
=
add_timeout_user
(
current
->
wait
->
timeout
,
if
(
!
(
current
->
wait
->
user
=
add_timeout_user
(
abstime_to_timeout
(
current
->
wait
->
when
)
,
thread_timeout
,
current
->
wait
)))
{
end_wait
(
current
,
get_error
()
);
return
timeout
;
return
;
}
}
current
->
wait
->
cookie
=
cookie
;
set_error
(
STATUS_PENDING
);
return
timeout
;
return
;
}
/* attempt to wake threads sleeping on the object wait queue */
...
...
@@ -1577,7 +1576,7 @@ DECL_HANDLER(select)
release_object
(
apc
);
}
reply
->
timeout
=
select_on
(
&
select_op
,
op_size
,
req
->
cookie
,
req
->
flags
,
req
->
timeout
);
select_on
(
&
select_op
,
op_size
,
req
->
cookie
,
req
->
flags
,
req
->
timeout
);
while
(
get_error
()
==
STATUS_USER_APC
)
{
...
...
server/trace.c
View file @
321d26cb
...
...
@@ -88,6 +88,12 @@ static void dump_timeout( const char *prefix, const timeout_t *time )
fprintf
(
stderr
,
"%s%s"
,
prefix
,
get_timeout_str
(
*
time
)
);
}
static
void
dump_abstime
(
const
char
*
prefix
,
const
abstime_t
*
when
)
{
timeout_t
timeout
=
abstime_to_timeout
(
*
when
);
dump_timeout
(
prefix
,
&
timeout
);
}
static
void
dump_uint64
(
const
char
*
prefix
,
const
unsigned
__int64
*
val
)
{
if
((
unsigned
int
)
*
val
!=
*
val
)
...
...
@@ -1581,7 +1587,7 @@ static void dump_select_request( const struct select_request *req )
{
fprintf
(
stderr
,
" flags=%d"
,
req
->
flags
);
dump_uint64
(
", cookie="
,
&
req
->
cookie
);
dump_
timeout
(
", timeout="
,
&
req
->
timeout
);
dump_
abstime
(
", timeout="
,
&
req
->
timeout
);
fprintf
(
stderr
,
", prev_apc=%04x"
,
req
->
prev_apc
);
dump_varargs_apc_result
(
", result="
,
cur_size
);
dump_varargs_select_op
(
", data="
,
cur_size
);
...
...
@@ -1589,8 +1595,7 @@ static void dump_select_request( const struct select_request *req )
static
void
dump_select_reply
(
const
struct
select_reply
*
req
)
{
dump_timeout
(
" timeout="
,
&
req
->
timeout
);
dump_apc_call
(
", call="
,
&
req
->
call
);
dump_apc_call
(
" call="
,
&
req
->
call
);
fprintf
(
stderr
,
", apc_handle=%04x"
,
req
->
apc_handle
);
}
...
...
tools/make_requests
View file @
321d26cb
...
...
@@ -43,6 +43,7 @@ my %formats =
"mem_size_t"
=>
[
8
,
8
,
"&dump_uint64"
],
"affinity_t"
=>
[
8
,
8
,
"&dump_uint64"
],
"timeout_t"
=>
[
8
,
8
,
"&dump_timeout"
],
"abstime_t"
=>
[
8
,
8
,
"&dump_abstime"
],
"rectangle_t"
=>
[
16
,
4
,
"&dump_rectangle"
],
"char_info_t"
=>
[
4
,
2
,
"&dump_char_info"
],
"apc_call_t"
=>
[
40
,
8
,
"&dump_apc_call"
],
...
...
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