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
93fb921c
Commit
93fb921c
authored
Oct 19, 2020
by
Zebediah Figura
Committed by
Alexandre Julliard
Oct 20, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ws2_32: Use server-side async I/O in accept().
Signed-off-by:
Zebediah Figura
<
z.figura12@gmail.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
0bbd3f66
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
91 additions
and
46 deletions
+91
-46
socket.c
dlls/ws2_32/socket.c
+33
-38
async.c
server/async.c
+5
-0
file.h
server/file.h
+1
-0
sock.c
server/sock.c
+52
-8
No files found.
dlls/ws2_32/socket.c
View file @
93fb921c
...
...
@@ -2673,55 +2673,50 @@ static int WS2_register_async_shutdown( SOCKET s, int type )
/***********************************************************************
* accept (WS2_32.1)
*/
SOCKET
WINAPI
WS_accept
(
SOCKET
s
,
struct
WS_sockaddr
*
addr
,
int
*
addrlen32
)
SOCKET
WINAPI
WS_accept
(
SOCKET
s
,
struct
WS_sockaddr
*
addr
,
int
*
len
)
{
DWORD
err
;
int
fd
;
BOOL
is_blocking
;
IO_STATUS_BLOCK
io
;
NTSTATUS
status
;
obj_handle_t
accept_handle
;
HANDLE
sync_event
;
SOCKET
ret
;
TRACE
(
"socket %04lx
\n
"
,
s
);
err
=
sock_is_blocking
(
s
,
&
is_blocking
);
if
(
err
)
goto
error
;
TRACE
(
"%#lx
\n
"
,
s
);
for
(;;)
if
(
!
(
sync_event
=
CreateEventW
(
NULL
,
TRUE
,
FALSE
,
NULL
)))
return
INVALID_SOCKET
;
status
=
NtDeviceIoControlFile
(
SOCKET2HANDLE
(
s
),
(
HANDLE
)((
ULONG_PTR
)
sync_event
|
0
),
NULL
,
NULL
,
&
io
,
IOCTL_AFD_ACCEPT
,
NULL
,
0
,
&
accept_handle
,
sizeof
(
accept_handle
)
);
if
(
status
==
STATUS_PENDING
)
{
status
=
NtDeviceIoControlFile
(
SOCKET2HANDLE
(
s
),
NULL
,
NULL
,
NULL
,
&
io
,
IOCTL_AFD_ACCEPT
,
NULL
,
0
,
&
accept_handle
,
sizeof
(
accept_handle
)
);
if
(
!
status
)
if
(
WaitForSingleObject
(
sync_event
,
INFINITE
)
==
WAIT_FAILED
)
{
SOCKET
as
=
HANDLE2SOCKET
(
wine_server_ptr_handle
(
accept_handle
));
CloseHandle
(
sync_event
);
return
SOCKET_ERROR
;
}
status
=
io
.
u
.
Status
;
}
CloseHandle
(
sync_event
);
if
(
status
)
{
WARN
(
"failed; status %#x
\n
"
,
status
);
WSASetLastError
(
NtStatusToWSAError
(
status
)
);
return
INVALID_SOCKET
;
}
if
(
!
socket_list_add
(
as
))
{
CloseHandle
(
SOCKET2HANDLE
(
as
));
return
SOCKET_ERROR
;
}
if
(
addr
&&
addrlen32
&&
WS_getpeername
(
as
,
addr
,
addrlen32
))
{
WS_closesocket
(
as
);
return
SOCKET_ERROR
;
}
TRACE
(
"
\t
accepted %04lx
\n
"
,
as
);
return
as
;
}
err
=
NtStatusToWSAError
(
status
);
if
(
!
is_blocking
)
break
;
if
(
err
!=
WSAEWOULDBLOCK
)
break
;
fd
=
get_sock_fd
(
s
,
FILE_READ_DATA
,
NULL
);
/* block here */
do_block
(
fd
,
POLLIN
,
-
1
);
_sync_sock_state
(
s
);
/* let wineserver notice connection */
release_sock_fd
(
s
,
fd
);
ret
=
HANDLE2SOCKET
(
wine_server_ptr_handle
(
accept_handle
));
if
(
!
socket_list_add
(
ret
))
{
CloseHandle
(
SOCKET2HANDLE
(
ret
)
);
return
INVALID_SOCKET
;
}
if
(
addr
&&
len
&&
WS_getpeername
(
ret
,
addr
,
len
))
{
WS_closesocket
(
ret
);
return
INVALID_SOCKET
;
}
error:
WARN
(
" -> ERROR %d
\n
"
,
err
);
SetLastError
(
err
);
return
INVALID_SOCKET
;
TRACE
(
"returning %#lx
\n
"
,
ret
);
return
ret
;
}
/***********************************************************************
...
...
server/async.c
View file @
93fb921c
...
...
@@ -542,6 +542,11 @@ struct iosb *async_get_iosb( struct async *async )
return
async
->
iosb
?
(
struct
iosb
*
)
grab_object
(
async
->
iosb
)
:
NULL
;
}
struct
thread
*
async_get_thread
(
struct
async
*
async
)
{
return
async
->
thread
;
}
int
async_is_blocking
(
struct
async
*
async
)
{
return
!
async
->
event
&&
!
async
->
data
.
apc
&&
!
async
->
data
.
apc_context
;
...
...
server/file.h
View file @
93fb921c
...
...
@@ -221,6 +221,7 @@ extern struct completion *fd_get_completion( struct fd *fd, apc_param_t *p_key )
extern
void
fd_copy_completion
(
struct
fd
*
src
,
struct
fd
*
dst
);
extern
struct
iosb
*
create_iosb
(
const
void
*
in_data
,
data_size_t
in_size
,
data_size_t
out_size
);
extern
struct
iosb
*
async_get_iosb
(
struct
async
*
async
);
extern
struct
thread
*
async_get_thread
(
struct
async
*
async
);
extern
int
async_is_blocking
(
struct
async
*
async
);
extern
struct
async
*
find_pending_async
(
struct
async_queue
*
queue
);
extern
void
cancel_process_asyncs
(
struct
process
*
process
);
...
...
server/sock.c
View file @
93fb921c
...
...
@@ -175,6 +175,7 @@ static void sock_queue_async( struct fd *fd, struct async *async, int type, int
static
void
sock_reselect_async
(
struct
fd
*
fd
,
struct
async_queue
*
queue
);
static
int
accept_into_socket
(
struct
sock
*
sock
,
struct
sock
*
acceptsock
);
static
struct
sock
*
accept_socket
(
struct
sock
*
sock
);
static
int
sock_get_ntstatus
(
int
err
);
static
unsigned
int
sock_get_error
(
int
err
);
...
...
@@ -448,7 +449,7 @@ static inline int sock_error( struct fd *fd )
static
void
free_accept_req
(
struct
accept_req
*
req
)
{
list_remove
(
&
req
->
entry
);
req
->
acceptsock
->
accept_recv_req
=
NULL
;
if
(
req
->
acceptsock
)
req
->
acceptsock
->
accept_recv_req
=
NULL
;
release_object
(
req
->
async
);
free
(
req
);
}
...
...
@@ -527,11 +528,37 @@ static void complete_async_accept( struct sock *sock, struct accept_req *req )
if
(
debug_level
)
fprintf
(
stderr
,
"completing accept request for socket %p
\n
"
,
sock
);
if
(
!
accept_into_socket
(
sock
,
acceptsock
))
return
;
if
(
acceptsock
)
{
if
(
!
accept_into_socket
(
sock
,
acceptsock
))
return
;
iosb
=
async_get_iosb
(
async
);
fill_accept_output
(
req
,
iosb
);
release_object
(
iosb
);
iosb
=
async_get_iosb
(
async
);
fill_accept_output
(
req
,
iosb
);
release_object
(
iosb
);
}
else
{
obj_handle_t
handle
;
if
(
!
(
acceptsock
=
accept_socket
(
sock
)))
return
;
handle
=
alloc_handle_no_access_check
(
async_get_thread
(
async
)
->
process
,
&
acceptsock
->
obj
,
GENERIC_READ
|
GENERIC_WRITE
|
SYNCHRONIZE
,
OBJ_INHERIT
);
acceptsock
->
wparam
=
handle
;
release_object
(
acceptsock
);
if
(
!
handle
)
return
;
iosb
=
async_get_iosb
(
async
);
if
(
!
(
iosb
->
out_data
=
malloc
(
sizeof
(
handle
)
)))
{
release_object
(
iosb
);
return
;
}
iosb
->
status
=
STATUS_SUCCESS
;
iosb
->
out_size
=
sizeof
(
handle
);
memcpy
(
iosb
->
out_data
,
&
handle
,
sizeof
(
handle
)
);
release_object
(
iosb
);
set_error
(
STATUS_ALERTED
);
}
}
static
void
complete_async_accept_recv
(
struct
accept_req
*
req
)
...
...
@@ -1344,8 +1371,11 @@ static struct accept_req *alloc_accept_req( struct sock *acceptsock, struct asyn
req
->
accepted
=
0
;
req
->
recv_len
=
0
;
req
->
local_len
=
0
;
req
->
recv_len
=
params
->
recv_len
;
req
->
local_len
=
params
->
local_len
;
if
(
params
)
{
req
->
recv_len
=
params
->
recv_len
;
req
->
local_len
=
params
->
local_len
;
}
}
return
req
;
}
...
...
@@ -1384,7 +1414,21 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
return
0
;
}
if
(
!
(
acceptsock
=
accept_socket
(
sock
)))
return
0
;
if
(
!
(
acceptsock
=
accept_socket
(
sock
)))
{
struct
accept_req
*
req
;
if
(
sock
->
state
&
FD_WINE_NONBLOCKING
)
return
0
;
if
(
get_error
()
!=
(
0xc0010000
|
WSAEWOULDBLOCK
))
return
0
;
if
(
!
(
req
=
alloc_accept_req
(
NULL
,
async
,
NULL
)))
return
0
;
list_add_tail
(
&
sock
->
accept_list
,
&
req
->
entry
);
queue_async
(
&
sock
->
accept_q
,
async
);
sock_reselect
(
sock
);
set_error
(
STATUS_PENDING
);
return
1
;
}
handle
=
alloc_handle
(
current
->
process
,
&
acceptsock
->
obj
,
GENERIC_READ
|
GENERIC_WRITE
|
SYNCHRONIZE
,
OBJ_INHERIT
);
acceptsock
->
wparam
=
handle
;
...
...
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