Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
b75ae8c3
Commit
b75ae8c3
authored
Aug 25, 2020
by
Jacek Caban
Committed by
Alexandre Julliard
Aug 26, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Support blocking console host ioctls.
Signed-off-by:
Jacek Caban
<
jacek@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
4225ec99
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
73 additions
and
9 deletions
+73
-9
server_protocol.h
include/wine/server_protocol.h
+3
-1
console.c
server/console.c
+65
-6
protocol.def
server/protocol.def
+1
-0
request.h
server/request.h
+3
-2
trace.c
server/trace.c
+1
-0
No files found.
include/wine/server_protocol.h
View file @
b75ae8c3
...
...
@@ -1943,8 +1943,10 @@ struct get_next_console_request_request
struct
request_header
__header
;
obj_handle_t
handle
;
int
signal
;
int
read
;
unsigned
int
status
;
/* VARARG(out_data,bytes); */
char
__pad_28
[
4
];
};
struct
get_next_console_request_reply
{
...
...
@@ -6333,7 +6335,7 @@ union generic_reply
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 63
8
#define SERVER_PROTOCOL_VERSION 63
9
/* ### protocol_version end ### */
...
...
server/console.c
View file @
b75ae8c3
...
...
@@ -192,6 +192,7 @@ struct console_server
struct
object
obj
;
/* object header */
struct
console_input
*
console
;
/* attached console */
struct
list
queue
;
/* ioctl queue */
struct
list
read_queue
;
/* blocking read queue */
int
busy
;
/* flag if server processing an ioctl */
};
...
...
@@ -577,6 +578,12 @@ static void disconnect_console_server( struct console_server *server )
list_remove
(
&
call
->
entry
);
console_host_ioctl_terminate
(
call
,
STATUS_CANCELLED
);
}
while
(
!
list_empty
(
&
server
->
read_queue
))
{
struct
console_host_ioctl
*
call
=
LIST_ENTRY
(
list_head
(
&
server
->
read_queue
),
struct
console_host_ioctl
,
entry
);
list_remove
(
&
call
->
entry
);
console_host_ioctl_terminate
(
call
,
STATUS_CANCELLED
);
}
if
(
server
->
console
)
{
...
...
@@ -1638,10 +1645,16 @@ static struct object *create_console_server( void )
server
->
console
=
NULL
;
server
->
busy
=
0
;
list_init
(
&
server
->
queue
);
list_init
(
&
server
->
read_queue
);
return
&
server
->
obj
;
}
static
int
is_blocking_read_ioctl
(
unsigned
int
code
)
{
return
code
==
IOCTL_CONDRV_READ_INPUT
;
}
static
int
console_input_ioctl
(
struct
fd
*
fd
,
ioctl_code_t
code
,
struct
async
*
async
)
{
struct
console_input
*
console
=
get_fd_user
(
fd
);
...
...
@@ -2385,11 +2398,10 @@ DECL_HANDLER(get_console_wait_event)
/* retrieve the next pending console ioctl request */
DECL_HANDLER
(
get_next_console_request
)
{
struct
console_host_ioctl
*
ioctl
=
NULL
;
struct
console_host_ioctl
*
ioctl
=
NULL
,
*
next
;
struct
console_server
*
server
;
struct
iosb
*
iosb
=
NULL
;
server
=
(
struct
console_server
*
)
get_handle_obj
(
current
->
process
,
req
->
handle
,
0
,
&
console_server_ops
);
if
(
!
server
)
return
;
...
...
@@ -2403,12 +2415,30 @@ DECL_HANDLER(get_next_console_request)
if
(
req
->
signal
)
set_event
(
server
->
console
->
event
);
else
reset_event
(
server
->
console
->
event
);
/* set result of previous ioctl, if any */
if
(
server
->
busy
)
if
(
req
->
read
)
{
unsigned
int
status
=
req
->
status
;
/* set result of current pending ioctl */
if
(
list_empty
(
&
server
->
read_queue
))
{
set_error
(
STATUS_INVALID_HANDLE
);
release_object
(
server
);
return
;
}
ioctl
=
LIST_ENTRY
(
list_head
(
&
server
->
read_queue
),
struct
console_host_ioctl
,
entry
);
list_remove
(
&
ioctl
->
entry
);
list_move_tail
(
&
server
->
queue
,
&
server
->
read_queue
);
}
else
if
(
server
->
busy
)
{
/* set result of previous ioctl */
ioctl
=
LIST_ENTRY
(
list_head
(
&
server
->
queue
),
struct
console_host_ioctl
,
entry
);
list_remove
(
&
ioctl
->
entry
);
}
if
(
ioctl
)
{
unsigned
int
status
=
req
->
status
;
if
(
ioctl
->
async
)
{
iosb
=
async_get_iosb
(
ioctl
->
async
);
...
...
@@ -2430,9 +2460,32 @@ DECL_HANDLER(get_next_console_request)
}
console_host_ioctl_terminate
(
ioctl
,
status
);
if
(
iosb
)
release_object
(
iosb
);
if
(
req
->
read
)
{
release_object
(
server
);
return
;
}
server
->
busy
=
0
;
}
/* if we have a blocking read ioctl in queue head and previous blocking read is still waiting,
* move it to read queue for execution after current read is complete. move all blocking
* ioctl at the same time to preserve their order. */
if
(
!
list_empty
(
&
server
->
queue
)
&&
!
list_empty
(
&
server
->
read_queue
))
{
ioctl
=
LIST_ENTRY
(
list_head
(
&
server
->
queue
),
struct
console_host_ioctl
,
entry
);
if
(
is_blocking_read_ioctl
(
ioctl
->
code
))
{
LIST_FOR_EACH_ENTRY_SAFE
(
ioctl
,
next
,
&
server
->
queue
,
struct
console_host_ioctl
,
entry
)
{
if
(
!
is_blocking_read_ioctl
(
ioctl
->
code
))
continue
;
list_remove
(
&
ioctl
->
entry
);
list_add_tail
(
&
server
->
read_queue
,
&
ioctl
->
entry
);
}
}
}
/* return the next ioctl */
if
(
!
list_empty
(
&
server
->
queue
))
{
...
...
@@ -2450,7 +2503,13 @@ DECL_HANDLER(get_next_console_request)
iosb
->
in_data
=
NULL
;
}
server
->
busy
=
1
;
if
(
is_blocking_read_ioctl
(
ioctl
->
code
))
{
list_remove
(
&
ioctl
->
entry
);
assert
(
list_empty
(
&
server
->
read_queue
));
list_add_tail
(
&
server
->
read_queue
,
&
ioctl
->
entry
);
}
else
server
->
busy
=
1
;
}
else
{
...
...
server/protocol.def
View file @
b75ae8c3
...
...
@@ -1526,6 +1526,7 @@ enum server_fd_type
@REQ(get_next_console_request)
obj_handle_t handle; /* console server handle */
int signal; /* server signal state */
int read; /* 1 if reporting result of blocked read ioctl */
unsigned int status; /* status of previous ioctl */
VARARG(out_data,bytes); /* out_data of previous ioctl */
@REPLY
...
...
server/request.h
View file @
b75ae8c3
...
...
@@ -1136,8 +1136,9 @@ C_ASSERT( FIELD_OFFSET(struct send_console_signal_request, group_id) == 16 );
C_ASSERT
(
sizeof
(
struct
send_console_signal_request
)
==
24
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_next_console_request_request
,
handle
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_next_console_request_request
,
signal
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_next_console_request_request
,
status
)
==
20
);
C_ASSERT
(
sizeof
(
struct
get_next_console_request_request
)
==
24
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_next_console_request_request
,
read
)
==
20
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_next_console_request_request
,
status
)
==
24
);
C_ASSERT
(
sizeof
(
struct
get_next_console_request_request
)
==
32
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_next_console_request_reply
,
code
)
==
8
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_next_console_request_reply
,
out_size
)
==
12
);
C_ASSERT
(
sizeof
(
struct
get_next_console_request_reply
)
==
16
);
...
...
server/trace.c
View file @
b75ae8c3
...
...
@@ -2098,6 +2098,7 @@ static void dump_get_next_console_request_request( const struct get_next_console
{
fprintf
(
stderr
,
" handle=%04x"
,
req
->
handle
);
fprintf
(
stderr
,
", signal=%d"
,
req
->
signal
);
fprintf
(
stderr
,
", read=%d"
,
req
->
read
);
fprintf
(
stderr
,
", status=%08x"
,
req
->
status
);
dump_varargs_bytes
(
", out_data="
,
cur_size
);
}
...
...
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