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
f016a963
Commit
f016a963
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 monotonic clock for relative timeouts.
Signed-off-by:
Piotr Caban
<
piotr@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
9bfbb486
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
69 additions
and
16 deletions
+69
-16
server_protocol.h
include/wine/server_protocol.h
+3
-0
fd.c
server/fd.c
+43
-8
file.h
server/file.h
+6
-0
protocol.def
server/protocol.def
+3
-0
request.c
server/request.c
+7
-7
request.h
server/request.h
+7
-1
No files found.
include/wine/server_protocol.h
View file @
f016a963
...
@@ -199,6 +199,9 @@ typedef __int64 timeout_t;
...
@@ -199,6 +199,9 @@ typedef __int64 timeout_t;
#define TIMEOUT_INFINITE (((timeout_t)0x7fffffff) << 32 | 0xffffffff)
#define TIMEOUT_INFINITE (((timeout_t)0x7fffffff) << 32 | 0xffffffff)
typedef
__int64
abstime_t
;
typedef
struct
typedef
struct
{
{
unsigned
int
debug_flags
;
unsigned
int
debug_flags
;
...
...
server/fd.c
View file @
f016a963
...
@@ -364,13 +364,15 @@ static file_pos_t max_unix_offset = OFF_T_MAX;
...
@@ -364,13 +364,15 @@ static file_pos_t max_unix_offset = OFF_T_MAX;
struct
timeout_user
struct
timeout_user
{
{
struct
list
entry
;
/* entry in sorted timeout list */
struct
list
entry
;
/* entry in sorted timeout list */
timeout_t
when
;
/* timeout expiry (absolute time)
*/
abstime_t
when
;
/* timeout expiry
*/
timeout_callback
callback
;
/* callback function */
timeout_callback
callback
;
/* callback function */
void
*
private
;
/* callback private data */
void
*
private
;
/* callback private data */
};
};
static
struct
list
timeout_list
=
LIST_INIT
(
timeout_list
);
/* sorted timeouts list */
static
struct
list
abs_timeout_list
=
LIST_INIT
(
abs_timeout_list
);
/* sorted absolute timeouts list */
static
struct
list
rel_timeout_list
=
LIST_INIT
(
rel_timeout_list
);
/* sorted relative timeouts list */
timeout_t
current_time
;
timeout_t
current_time
;
timeout_t
monotonic_time
;
void
set_current_time
(
void
)
void
set_current_time
(
void
)
{
{
...
@@ -378,6 +380,7 @@ void set_current_time(void)
...
@@ -378,6 +380,7 @@ void set_current_time(void)
struct
timeval
now
;
struct
timeval
now
;
gettimeofday
(
&
now
,
NULL
);
gettimeofday
(
&
now
,
NULL
);
current_time
=
(
timeout_t
)
now
.
tv_sec
*
TICKS_PER_SEC
+
now
.
tv_usec
*
10
+
ticks_1601_to_1970
;
current_time
=
(
timeout_t
)
now
.
tv_sec
*
TICKS_PER_SEC
+
now
.
tv_usec
*
10
+
ticks_1601_to_1970
;
monotonic_time
=
monotonic_counter
();
}
}
/* add a timeout user */
/* add a timeout user */
...
@@ -387,17 +390,28 @@ struct timeout_user *add_timeout_user( timeout_t when, timeout_callback func, vo
...
@@ -387,17 +390,28 @@ struct timeout_user *add_timeout_user( timeout_t when, timeout_callback func, vo
struct
list
*
ptr
;
struct
list
*
ptr
;
if
(
!
(
user
=
mem_alloc
(
sizeof
(
*
user
)
)))
return
NULL
;
if
(
!
(
user
=
mem_alloc
(
sizeof
(
*
user
)
)))
return
NULL
;
user
->
when
=
(
when
>
0
)
?
when
:
current_time
-
when
;
user
->
when
=
timeout_to_abstime
(
when
)
;
user
->
callback
=
func
;
user
->
callback
=
func
;
user
->
private
=
private
;
user
->
private
=
private
;
/* Now insert it in the linked list */
/* Now insert it in the linked list */
LIST_FOR_EACH
(
ptr
,
&
timeout_list
)
if
(
user
->
when
>
0
)
{
LIST_FOR_EACH
(
ptr
,
&
abs_timeout_list
)
{
{
struct
timeout_user
*
timeout
=
LIST_ENTRY
(
ptr
,
struct
timeout_user
,
entry
);
struct
timeout_user
*
timeout
=
LIST_ENTRY
(
ptr
,
struct
timeout_user
,
entry
);
if
(
timeout
->
when
>=
user
->
when
)
break
;
if
(
timeout
->
when
>=
user
->
when
)
break
;
}
}
}
else
{
LIST_FOR_EACH
(
ptr
,
&
rel_timeout_list
)
{
struct
timeout_user
*
timeout
=
LIST_ENTRY
(
ptr
,
struct
timeout_user
,
entry
);
if
(
timeout
->
when
<=
user
->
when
)
break
;
}
}
list_add_before
(
ptr
,
&
user
->
entry
);
list_add_before
(
ptr
,
&
user
->
entry
);
return
user
;
return
user
;
}
}
...
@@ -851,14 +865,15 @@ static void remove_poll_user( struct fd *fd, int user )
...
@@ -851,14 +865,15 @@ static void remove_poll_user( struct fd *fd, int user )
/* process pending timeouts and return the time until the next timeout, in milliseconds */
/* process pending timeouts and return the time until the next timeout, in milliseconds */
static
int
get_next_timeout
(
void
)
static
int
get_next_timeout
(
void
)
{
{
if
(
!
list_empty
(
&
timeout_list
))
if
(
!
list_empty
(
&
abs_timeout_list
)
||
!
list_empty
(
&
rel_
timeout_list
))
{
{
struct
list
expired_list
,
*
ptr
;
struct
list
expired_list
,
*
ptr
;
int
ret
=
-
1
;
/* first remove all expired timers from the list */
/* first remove all expired timers from the list */
list_init
(
&
expired_list
);
list_init
(
&
expired_list
);
while
((
ptr
=
list_head
(
&
timeout_list
))
!=
NULL
)
while
((
ptr
=
list_head
(
&
abs_
timeout_list
))
!=
NULL
)
{
{
struct
timeout_user
*
timeout
=
LIST_ENTRY
(
ptr
,
struct
timeout_user
,
entry
);
struct
timeout_user
*
timeout
=
LIST_ENTRY
(
ptr
,
struct
timeout_user
,
entry
);
...
@@ -869,6 +884,17 @@ static int get_next_timeout(void)
...
@@ -869,6 +884,17 @@ static int get_next_timeout(void)
}
}
else
break
;
else
break
;
}
}
while
((
ptr
=
list_head
(
&
rel_timeout_list
))
!=
NULL
)
{
struct
timeout_user
*
timeout
=
LIST_ENTRY
(
ptr
,
struct
timeout_user
,
entry
);
if
(
-
timeout
->
when
<=
monotonic_time
)
{
list_remove
(
&
timeout
->
entry
);
list_add_tail
(
&
expired_list
,
&
timeout
->
entry
);
}
else
break
;
}
/* now call the callback for all the removed timers */
/* now call the callback for all the removed timers */
...
@@ -880,13 +906,22 @@ static int get_next_timeout(void)
...
@@ -880,13 +906,22 @@ static int get_next_timeout(void)
free
(
timeout
);
free
(
timeout
);
}
}
if
((
ptr
=
list_head
(
&
timeout_list
))
!=
NULL
)
if
((
ptr
=
list_head
(
&
abs_
timeout_list
))
!=
NULL
)
{
{
struct
timeout_user
*
timeout
=
LIST_ENTRY
(
ptr
,
struct
timeout_user
,
entry
);
struct
timeout_user
*
timeout
=
LIST_ENTRY
(
ptr
,
struct
timeout_user
,
entry
);
int
diff
=
(
timeout
->
when
-
current_time
+
9999
)
/
10000
;
int
diff
=
(
timeout
->
when
-
current_time
+
9999
)
/
10000
;
if
(
diff
<
0
)
diff
=
0
;
if
(
diff
<
0
)
diff
=
0
;
ret
urn
diff
;
ret
=
diff
;
}
}
if
((
ptr
=
list_head
(
&
rel_timeout_list
))
!=
NULL
)
{
struct
timeout_user
*
timeout
=
LIST_ENTRY
(
ptr
,
struct
timeout_user
,
entry
);
int
diff
=
(
-
timeout
->
when
-
monotonic_time
+
9999
)
/
10000
;
if
(
diff
<
0
)
diff
=
0
;
if
(
ret
==
-
1
||
diff
<
ret
)
ret
=
diff
;
}
return
ret
;
}
}
return
-
1
;
/* no pending timeouts */
return
-
1
;
/* no pending timeouts */
}
}
...
...
server/file.h
View file @
f016a963
...
@@ -129,11 +129,17 @@ static inline struct fd *get_obj_fd( struct object *obj ) { return obj->ops->get
...
@@ -129,11 +129,17 @@ static inline struct fd *get_obj_fd( struct object *obj ) { return obj->ops->get
struct
timeout_user
;
struct
timeout_user
;
extern
timeout_t
current_time
;
extern
timeout_t
current_time
;
extern
timeout_t
monotonic_time
;
#define TICKS_PER_SEC 10000000
#define TICKS_PER_SEC 10000000
typedef
void
(
*
timeout_callback
)(
void
*
private
);
typedef
void
(
*
timeout_callback
)(
void
*
private
);
static
inline
abstime_t
timeout_to_abstime
(
timeout_t
timeout
)
{
return
timeout
>
0
?
timeout
:
timeout
-
monotonic_time
;
}
extern
void
set_current_time
(
void
);
extern
void
set_current_time
(
void
);
extern
struct
timeout_user
*
add_timeout_user
(
timeout_t
when
,
timeout_callback
func
,
void
*
private
);
extern
struct
timeout_user
*
add_timeout_user
(
timeout_t
when
,
timeout_callback
func
,
void
*
private
);
extern
void
remove_timeout_user
(
struct
timeout_user
*
user
);
extern
void
remove_timeout_user
(
struct
timeout_user
*
user
);
...
...
server/protocol.def
View file @
f016a963
...
@@ -214,6 +214,9 @@ struct wake_up_reply
...
@@ -214,6 +214,9 @@ struct wake_up_reply
typedef __int64 timeout_t;
typedef __int64 timeout_t;
#define TIMEOUT_INFINITE (((timeout_t)0x7fffffff) << 32 | 0xffffffff)
#define TIMEOUT_INFINITE (((timeout_t)0x7fffffff) << 32 | 0xffffffff)
/* absolute timeout, negative means that monotonic clock is used */
typedef __int64 abstime_t;
/* structure for process startup info */
/* structure for process startup info */
typedef struct
typedef struct
{
{
...
...
server/request.c
View file @
f016a963
...
@@ -522,8 +522,8 @@ int send_client_fd( struct process *process, int fd, obj_handle_t handle )
...
@@ -522,8 +522,8 @@ int send_client_fd( struct process *process, int fd, obj_handle_t handle )
return
-
1
;
return
-
1
;
}
}
/*
get current tick count to return to client
*/
/*
return a monotonic time counter
*/
unsigned
int
get_tick_count
(
void
)
timeout_t
monotonic_counter
(
void
)
{
{
#ifdef __APPLE__
#ifdef __APPLE__
static
mach_timebase_info_data_t
timebase
;
static
mach_timebase_info_data_t
timebase
;
...
@@ -531,19 +531,19 @@ unsigned int get_tick_count(void)
...
@@ -531,19 +531,19 @@ unsigned int get_tick_count(void)
if
(
!
timebase
.
denom
)
mach_timebase_info
(
&
timebase
);
if
(
!
timebase
.
denom
)
mach_timebase_info
(
&
timebase
);
#ifdef HAVE_MACH_CONTINUOUS_TIME
#ifdef HAVE_MACH_CONTINUOUS_TIME
if
(
&
mach_continuous_time
!=
NULL
)
if
(
&
mach_continuous_time
!=
NULL
)
return
mach_continuous_time
()
*
timebase
.
numer
/
timebase
.
denom
/
100
0000
;
return
mach_continuous_time
()
*
timebase
.
numer
/
timebase
.
denom
/
100
;
#endif
#endif
return
mach_absolute_time
()
*
timebase
.
numer
/
timebase
.
denom
/
100
0000
;
return
mach_absolute_time
()
*
timebase
.
numer
/
timebase
.
denom
/
100
;
#elif defined(HAVE_CLOCK_GETTIME)
#elif defined(HAVE_CLOCK_GETTIME)
struct
timespec
ts
;
struct
timespec
ts
;
#ifdef CLOCK_MONOTONIC_RAW
#ifdef CLOCK_MONOTONIC_RAW
if
(
!
clock_gettime
(
CLOCK_MONOTONIC_RAW
,
&
ts
))
if
(
!
clock_gettime
(
CLOCK_MONOTONIC_RAW
,
&
ts
))
return
ts
.
tv_sec
*
1000
+
ts
.
tv_nsec
/
10000
00
;
return
(
timeout_t
)
ts
.
tv_sec
*
TICKS_PER_SEC
+
ts
.
tv_nsec
/
1
00
;
#endif
#endif
if
(
!
clock_gettime
(
CLOCK_MONOTONIC
,
&
ts
))
if
(
!
clock_gettime
(
CLOCK_MONOTONIC
,
&
ts
))
return
ts
.
tv_sec
*
1000
+
ts
.
tv_nsec
/
10000
00
;
return
(
timeout_t
)
ts
.
tv_sec
*
TICKS_PER_SEC
+
ts
.
tv_nsec
/
1
00
;
#endif
#endif
return
(
current_time
-
server_start_time
)
/
10000
;
return
current_time
-
server_start_time
;
}
}
static
void
master_socket_dump
(
struct
object
*
obj
,
int
verbose
)
static
void
master_socket_dump
(
struct
object
*
obj
,
int
verbose
)
...
...
server/request.h
View file @
f016a963
...
@@ -54,7 +54,7 @@ extern int receive_fd( struct process *process );
...
@@ -54,7 +54,7 @@ extern int receive_fd( struct process *process );
extern
int
send_client_fd
(
struct
process
*
process
,
int
fd
,
obj_handle_t
handle
);
extern
int
send_client_fd
(
struct
process
*
process
,
int
fd
,
obj_handle_t
handle
);
extern
void
read_request
(
struct
thread
*
thread
);
extern
void
read_request
(
struct
thread
*
thread
);
extern
void
write_reply
(
struct
thread
*
thread
);
extern
void
write_reply
(
struct
thread
*
thread
);
extern
unsigned
int
get_tick_count
(
void
);
extern
timeout_t
monotonic_counter
(
void
);
extern
void
open_master_socket
(
void
);
extern
void
open_master_socket
(
void
);
extern
void
close_master_socket
(
timeout_t
timeout
);
extern
void
close_master_socket
(
timeout_t
timeout
);
extern
void
shutdown_master_socket
(
void
);
extern
void
shutdown_master_socket
(
void
);
...
@@ -66,6 +66,12 @@ extern int server_dir_fd, config_dir_fd;
...
@@ -66,6 +66,12 @@ extern int server_dir_fd, config_dir_fd;
extern
void
trace_request
(
void
);
extern
void
trace_request
(
void
);
extern
void
trace_reply
(
enum
request
req
,
const
union
generic_reply
*
reply
);
extern
void
trace_reply
(
enum
request
req
,
const
union
generic_reply
*
reply
);
/* get current tick count to return to client */
static
inline
unsigned
int
get_tick_count
(
void
)
{
return
monotonic_counter
()
/
10000
;
}
/* get the request vararg data */
/* get the request vararg data */
static
inline
const
void
*
get_req_data
(
void
)
static
inline
const
void
*
get_req_data
(
void
)
{
{
...
...
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