Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-fonts
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
Aleksandr Isakov
wine-fonts
Commits
6267c4b8
Commit
6267c4b8
authored
Jul 06, 2020
by
Zebediah Figura
Committed by
Vitaly Lipatov
Jul 30, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server, ntdll: Implement message waits.
parent
3153d8d1
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
102 additions
and
3 deletions
+102
-3
esync.c
dlls/ntdll/unix/esync.c
+49
-2
server_protocol.h
include/wine/server_protocol.h
+15
-1
protocol.def
server/protocol.def
+5
-0
queue.c
server/queue.c
+21
-0
request.h
server/request.h
+4
-0
trace.c
server/trace.c
+8
-0
No files found.
dlls/ntdll/unix/esync.c
View file @
6267c4b8
...
...
@@ -475,12 +475,13 @@ static void update_grabbed_object( struct esync *obj )
/* A value of STATUS_NOT_IMPLEMENTED returned from this function means that we
* need to delegate to server_select(). */
NTSTATUS
esync_wait_objects
(
DWORD
count
,
const
HANDLE
*
handles
,
BOOLEAN
wait_any
,
static
NTSTATUS
__
esync_wait_objects
(
DWORD
count
,
const
HANDLE
*
handles
,
BOOLEAN
wait_any
,
BOOLEAN
alertable
,
const
LARGE_INTEGER
*
timeout
)
{
struct
esync
*
objs
[
MAXIMUM_WAIT_OBJECTS
];
struct
pollfd
fds
[
MAXIMUM_WAIT_OBJECTS
];
int
has_esync
=
0
,
has_server
=
0
;
BOOL
msgwait
=
FALSE
;
LONGLONG
timeleft
;
LARGE_INTEGER
now
;
ULONGLONG
end
;
...
...
@@ -508,6 +509,9 @@ NTSTATUS esync_wait_objects( DWORD count, const HANDLE *handles, BOOLEAN wait_an
return
ret
;
}
if
(
objs
[
count
-
1
]
&&
objs
[
count
-
1
]
->
type
==
ESYNC_QUEUE
)
msgwait
=
TRUE
;
if
(
has_esync
&&
has_server
)
FIXME
(
"Can't wait on esync and server objects at the same time!
\n
"
);
else
if
(
has_server
)
...
...
@@ -519,6 +523,9 @@ NTSTATUS esync_wait_objects( DWORD count, const HANDLE *handles, BOOLEAN wait_an
for
(
i
=
0
;
i
<
count
;
i
++
)
TRACE
(
" %p"
,
handles
[
i
]);
if
(
msgwait
)
TRACE
(
" or driver events"
);
if
(
!
timeout
)
TRACE
(
", timeout = INFINITE.
\n
"
);
else
...
...
@@ -558,7 +565,9 @@ NTSTATUS esync_wait_objects( DWORD count, const HANDLE *handles, BOOLEAN wait_an
int64_t
value
;
ssize_t
size
;
if
(
obj
->
type
==
ESYNC_MANUAL_EVENT
||
obj
->
type
==
ESYNC_MANUAL_SERVER
)
if
(
obj
->
type
==
ESYNC_MANUAL_EVENT
||
obj
->
type
==
ESYNC_MANUAL_SERVER
||
obj
->
type
==
ESYNC_QUEUE
)
{
/* Don't grab the object, just check if it's signaled. */
if
(
fds
[
i
].
revents
&
POLLIN
)
...
...
@@ -603,6 +612,44 @@ NTSTATUS esync_wait_objects( DWORD count, const HANDLE *handles, BOOLEAN wait_an
}
}
/* We need to let the server know when we are doing a message wait, and when we
* are done with one, so that all of the code surrounding hung queues works.
* We also need this for WaitForInputIdle(). */
static
void
server_set_msgwait
(
int
in_msgwait
)
{
SERVER_START_REQ
(
esync_msgwait
)
{
req
->
in_msgwait
=
in_msgwait
;
wine_server_call
(
req
);
}
SERVER_END_REQ
;
}
/* This is a very thin wrapper around the proper implementation above. The
* purpose is to make sure the server knows when we are doing a message wait.
* This is separated into a wrapper function since there are at least a dozen
* exit paths from esync_wait_objects(). */
NTSTATUS
esync_wait_objects
(
DWORD
count
,
const
HANDLE
*
handles
,
BOOLEAN
wait_any
,
BOOLEAN
alertable
,
const
LARGE_INTEGER
*
timeout
)
{
BOOL
msgwait
=
FALSE
;
struct
esync
*
obj
;
NTSTATUS
ret
;
if
(
count
&&
!
get_object
(
handles
[
count
-
1
],
&
obj
)
&&
obj
->
type
==
ESYNC_QUEUE
)
{
msgwait
=
TRUE
;
server_set_msgwait
(
1
);
}
ret
=
__esync_wait_objects
(
count
,
handles
,
wait_any
,
alertable
,
timeout
);
if
(
msgwait
)
server_set_msgwait
(
0
);
return
ret
;
}
void
esync_init
(
void
)
{
struct
stat
st
;
...
...
include/wine/server_protocol.h
View file @
6267c4b8
...
...
@@ -5521,6 +5521,17 @@ struct get_esync_fd_reply
};
struct
esync_msgwait_request
{
struct
request_header
__header
;
int
in_msgwait
;
};
struct
esync_msgwait_reply
{
struct
reply_header
__header
;
};
enum
request
{
REQ_new_process
,
...
...
@@ -5802,6 +5813,7 @@ enum request
REQ_get_next_thread
,
REQ_create_esync
,
REQ_get_esync_fd
,
REQ_esync_msgwait
,
REQ_NB_REQUESTS
};
...
...
@@ -6088,6 +6100,7 @@ union generic_request
struct
get_next_thread_request
get_next_thread_request
;
struct
create_esync_request
create_esync_request
;
struct
get_esync_fd_request
get_esync_fd_request
;
struct
esync_msgwait_request
esync_msgwait_request
;
};
union
generic_reply
{
...
...
@@ -6372,11 +6385,12 @@ union generic_reply
struct
get_next_thread_reply
get_next_thread_reply
;
struct
create_esync_reply
create_esync_reply
;
struct
get_esync_fd_reply
get_esync_fd_reply
;
struct
esync_msgwait_reply
esync_msgwait_reply
;
};
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 7
59
#define SERVER_PROTOCOL_VERSION 7
60
/* ### protocol_version end ### */
...
...
server/protocol.def
View file @
6267c4b8
...
...
@@ -3797,3 +3797,8 @@ enum esync_type
int type;
unsigned int shm_idx;
@END
/* Notify the server that we are doing a message wait or done with one. */
@REQ(esync_msgwait)
int in_msgwait; /* are we in a message wait? */
@END
server/queue.c
View file @
6267c4b8
...
...
@@ -144,6 +144,7 @@ struct msg_queue
int
keystate_lock
;
/* owns an input keystate lock */
unsigned
int
ignore_post_msg
;
/* ignore post messages newer than this unique id */
int
esync_fd
;
/* esync file descriptor (signalled on message) */
int
esync_in_msgwait
;
/* our thread is currently waiting on us */
};
struct
hotkey
...
...
@@ -317,6 +318,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
queue
->
keystate_lock
=
0
;
queue
->
ignore_post_msg
=
0
;
queue
->
esync_fd
=
-
1
;
queue
->
esync_in_msgwait
=
0
;
list_init
(
&
queue
->
send_result
);
list_init
(
&
queue
->
callback_result
);
list_init
(
&
queue
->
pending_timers
);
...
...
@@ -1001,6 +1003,10 @@ static int is_queue_hung( struct msg_queue *queue )
if
(
get_wait_queue_thread
(
entry
)
->
queue
==
queue
)
return
0
;
/* thread is waiting on queue -> not hung */
}
if
(
do_esync
()
&&
queue
->
esync_in_msgwait
)
return
0
;
/* thread is waiting on queue in absentia -> not hung */
return
1
;
}
...
...
@@ -3456,3 +3462,18 @@ DECL_HANDLER(update_rawinput_devices)
process
->
rawinput_mouse
=
find_rawinput_device
(
process
,
1
,
2
);
process
->
rawinput_kbd
=
find_rawinput_device
(
process
,
1
,
6
);
}
DECL_HANDLER
(
esync_msgwait
)
{
struct
msg_queue
*
queue
=
get_current_queue
();
if
(
!
queue
)
return
;
queue
->
esync_in_msgwait
=
req
->
in_msgwait
;
if
(
current
->
process
->
idle_event
&&
!
(
queue
->
wake_mask
&
QS_SMRESULT
))
set_event
(
current
->
process
->
idle_event
);
/* and start/stop waiting on the driver */
if
(
queue
->
fd
)
set_fd_events
(
queue
->
fd
,
req
->
in_msgwait
?
POLLIN
:
0
);
}
server/request.h
View file @
6267c4b8
...
...
@@ -398,6 +398,7 @@ DECL_HANDLER(resume_process);
DECL_HANDLER
(
get_next_thread
);
DECL_HANDLER
(
create_esync
);
DECL_HANDLER
(
get_esync_fd
);
DECL_HANDLER
(
esync_msgwait
);
#ifdef WANT_REQUEST_HANDLERS
...
...
@@ -683,6 +684,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(
req_handler
)
req_get_next_thread
,
(
req_handler
)
req_create_esync
,
(
req_handler
)
req_get_esync_fd
,
(
req_handler
)
req_esync_msgwait
,
};
C_ASSERT
(
sizeof
(
abstime_t
)
==
8
);
...
...
@@ -2286,6 +2288,8 @@ C_ASSERT( sizeof(struct get_esync_fd_request) == 16 );
C_ASSERT
(
FIELD_OFFSET
(
struct
get_esync_fd_reply
,
type
)
==
8
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_esync_fd_reply
,
shm_idx
)
==
12
);
C_ASSERT
(
sizeof
(
struct
get_esync_fd_reply
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
esync_msgwait_request
,
in_msgwait
)
==
12
);
C_ASSERT
(
sizeof
(
struct
esync_msgwait_request
)
==
16
);
#endif
/* WANT_REQUEST_HANDLERS */
...
...
server/trace.c
View file @
6267c4b8
...
...
@@ -4527,6 +4527,11 @@ static void dump_get_esync_fd_reply( const struct get_esync_fd_reply *req )
fprintf
(
stderr
,
", shm_idx=%08x"
,
req
->
shm_idx
);
}
static
void
dump_esync_msgwait_request
(
const
struct
esync_msgwait_request
*
req
)
{
fprintf
(
stderr
,
" in_msgwait=%d"
,
req
->
in_msgwait
);
}
static
const
dump_func
req_dumpers
[
REQ_NB_REQUESTS
]
=
{
(
dump_func
)
dump_new_process_request
,
(
dump_func
)
dump_get_new_process_info_request
,
...
...
@@ -4807,6 +4812,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_get_next_thread_request
,
(
dump_func
)
dump_create_esync_request
,
(
dump_func
)
dump_get_esync_fd_request
,
(
dump_func
)
dump_esync_msgwait_request
,
};
static
const
dump_func
reply_dumpers
[
REQ_NB_REQUESTS
]
=
{
...
...
@@ -5089,6 +5095,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_get_next_thread_reply
,
(
dump_func
)
dump_create_esync_reply
,
(
dump_func
)
dump_get_esync_fd_reply
,
NULL
,
};
static
const
char
*
const
req_names
[
REQ_NB_REQUESTS
]
=
{
...
...
@@ -5371,6 +5378,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"get_next_thread"
,
"create_esync"
,
"get_esync_fd"
,
"esync_msgwait"
,
};
static
const
struct
...
...
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