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
5eaba82a
Commit
5eaba82a
authored
Jun 10, 2021
by
Zebediah Figura
Committed by
Alexandre Julliard
Jun 11, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Use separate fields to track socket shutdown state.
Signed-off-by:
Zebediah Figura
<
z.figura12@gmail.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
5ee78d34
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
38 additions
and
21 deletions
+38
-21
sock.c
server/sock.c
+38
-21
No files found.
server/sock.c
View file @
5eaba82a
...
...
@@ -172,6 +172,8 @@ struct sock
struct
list
accept_list
;
/* list of pending accept requests */
struct
accept_req
*
accept_recv_req
;
/* pending accept-into request which will recv on this socket */
struct
connect_req
*
connect_req
;
/* pending connection request */
unsigned
int
rd_shutdown
:
1
;
/* is the read end shut down? */
unsigned
int
wr_shutdown
:
1
;
/* is the write end shut down? */
unsigned
int
wr_shutdown_pending
:
1
;
/* is a write shutdown pending? */
unsigned
int
nonblocking
:
1
;
/* is the socket nonblocking? */
};
...
...
@@ -781,9 +783,9 @@ static int sock_dispatch_asyncs( struct sock *sock, int event, int error )
int
status
=
sock_get_ntstatus
(
error
);
struct
accept_req
*
req
,
*
next
;
if
(
!
(
sock
->
state
&
FD_READ
)
)
if
(
sock
->
rd_shutdown
)
async_wake_up
(
&
sock
->
read_q
,
status
);
if
(
!
(
sock
->
state
&
FD_WRITE
)
)
if
(
sock
->
wr_shutdown
)
async_wake_up
(
&
sock
->
write_q
,
status
);
LIST_FOR_EACH_ENTRY_SAFE
(
req
,
next
,
&
sock
->
accept_list
,
struct
accept_req
,
entry
)
...
...
@@ -869,7 +871,7 @@ static void sock_poll_event( struct fd *fd, int event )
else
if
(
event
&
POLLOUT
)
{
/* we got connected */
sock
->
state
|=
FD_WINE_CONNECTED
|
FD_READ
|
FD_WRITE
;
sock
->
state
|=
FD_WINE_CONNECTED
;
sock
->
state
&=
~
FD_CONNECT
;
sock
->
connect_time
=
current_time
;
}
...
...
@@ -911,12 +913,12 @@ static void sock_poll_event( struct fd *fd, int event )
}
}
if
(
(
hangup_seen
||
event
&
(
POLLHUP
|
POLLERR
))
&&
(
sock
->
state
&
(
FD_READ
|
FD_WRITE
))
)
if
(
(
hangup_seen
||
event
&
(
POLLHUP
|
POLLERR
))
&&
(
!
sock
->
rd_shutdown
||
!
sock
->
wr_shutdown
)
)
{
error
=
error
?
error
:
sock_error
(
fd
);
if
(
(
event
&
POLLERR
)
||
(
sock_shutdown_type
==
SOCK_SHUTDOWN_EOF
&&
(
event
&
POLLHUP
)
))
sock
->
state
&=
~
FD_WRITE
;
sock
->
state
&=
~
FD_READ
;
sock
->
wr_shutdown
=
1
;
sock
->
rd_shutdown
=
1
;
if
(
debug_level
)
fprintf
(
stderr
,
"socket %p aborted by error %d, event: %x
\n
"
,
sock
,
error
,
event
);
...
...
@@ -969,7 +971,6 @@ static int sock_get_poll_events( struct fd *fd )
{
struct
sock
*
sock
=
get_fd_user
(
fd
);
unsigned
int
mask
=
sock
->
mask
&
~
sock
->
reported_events
;
unsigned
int
smask
=
sock
->
state
&
mask
;
struct
poll_req
*
req
;
int
ev
=
0
;
...
...
@@ -996,7 +997,12 @@ static int sock_get_poll_events( struct fd *fd )
{
if
(
async_waiting
(
&
sock
->
read_q
))
ev
|=
POLLIN
|
POLLPRI
;
}
else
if
(
smask
&
FD_READ
||
(
sock
->
state
&
FD_WINE_LISTENING
&&
mask
&
FD_ACCEPT
))
else
if
(
sock
->
state
&
FD_WINE_LISTENING
)
{
if
(
mask
&
FD_ACCEPT
)
ev
|=
POLLIN
;
}
else
if
(
!
sock
->
rd_shutdown
&&
(
mask
&
FD_READ
))
ev
|=
POLLIN
|
POLLPRI
;
/* We use POLLIN with 0 bytes recv() as FD_CLOSE indication for stream sockets. */
else
if
(
sock
->
type
==
WS_SOCK_STREAM
&&
(
mask
&
FD_CLOSE
)
&&
!
(
sock
->
reported_events
&
FD_READ
))
...
...
@@ -1006,7 +1012,7 @@ static int sock_get_poll_events( struct fd *fd )
{
if
(
async_waiting
(
&
sock
->
write_q
))
ev
|=
POLLOUT
;
}
else
if
(
smask
&
FD_WRITE
)
else
if
(
!
sock
->
wr_shutdown
&&
(
mask
&
FD_WRITE
)
)
ev
|=
POLLOUT
;
LIST_FOR_EACH_ENTRY
(
req
,
&
poll_list
,
struct
poll_req
,
entry
)
...
...
@@ -1039,18 +1045,30 @@ static void sock_queue_async( struct fd *fd, struct async *async, int type, int
switch
(
type
)
{
case
ASYNC_TYPE_READ
:
if
(
sock
->
rd_shutdown
)
{
set_error
(
STATUS_PIPE_DISCONNECTED
);
return
;
}
queue
=
&
sock
->
read_q
;
break
;
case
ASYNC_TYPE_WRITE
:
if
(
sock
->
wr_shutdown
)
{
set_error
(
STATUS_PIPE_DISCONNECTED
);
return
;
}
queue
=
&
sock
->
write_q
;
break
;
default:
set_error
(
STATUS_INVALID_PARAMETER
);
return
;
}
if
(
(
!
(
sock
->
state
&
(
FD_
READ
|
FD_
CONNECT
|
FD_WINE_LISTENING
)
)
&&
type
==
ASYNC_TYPE_READ
)
||
(
!
(
sock
->
state
&
(
FD_
WRITE
|
FD_
CONNECT
)
)
&&
type
==
ASYNC_TYPE_WRITE
)
)
if
(
(
!
(
sock
->
state
&
(
FD_CONNECT
|
FD_WINE_LISTENING
)
)
&&
type
==
ASYNC_TYPE_READ
)
||
(
!
(
sock
->
state
&
(
FD_CONNECT
)
)
&&
type
==
ASYNC_TYPE_WRITE
)
)
{
set_error
(
STATUS_PIPE_DISCONNECTED
);
return
;
...
...
@@ -1180,6 +1198,8 @@ static struct sock *create_socket(void)
sock
->
ifchange_obj
=
NULL
;
sock
->
accept_recv_req
=
NULL
;
sock
->
connect_req
=
NULL
;
sock
->
rd_shutdown
=
0
;
sock
->
wr_shutdown
=
0
;
sock
->
wr_shutdown_pending
=
0
;
sock
->
nonblocking
=
0
;
init_async_queue
(
&
sock
->
read_q
);
...
...
@@ -1339,7 +1359,6 @@ static int init_socket( struct sock *sock, int family, int type, int protocol, u
}
#endif
sock
->
state
=
(
type
!=
SOCK_STREAM
)
?
(
FD_READ
|
FD_WRITE
)
:
0
;
sock
->
flags
=
flags
;
sock
->
proto
=
protocol
;
sock
->
type
=
type
;
...
...
@@ -1404,7 +1423,7 @@ static struct sock *accept_socket( struct sock *sock )
}
/* newly created socket gets the same properties of the listening socket */
acceptsock
->
state
=
FD_WINE_CONNECTED
|
FD_READ
|
FD_WRITE
;
acceptsock
->
state
=
FD_WINE_CONNECTED
;
acceptsock
->
nonblocking
=
sock
->
nonblocking
;
acceptsock
->
mask
=
sock
->
mask
;
acceptsock
->
proto
=
sock
->
proto
;
...
...
@@ -1458,7 +1477,7 @@ static int accept_into_socket( struct sock *sock, struct sock *acceptsock )
return
FALSE
;
}
acceptsock
->
state
|=
FD_WINE_CONNECTED
|
FD_READ
|
FD_WRITE
;
acceptsock
->
state
|=
FD_WINE_CONNECTED
;
acceptsock
->
pending_events
=
0
;
acceptsock
->
reported_events
=
0
;
acceptsock
->
proto
=
sock
->
proto
;
...
...
@@ -1808,7 +1827,7 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
if
(
!
ret
)
{
sock
->
state
|=
FD_WINE_CONNECTED
|
FD_READ
|
FD_WRITE
;
sock
->
state
|=
FD_WINE_CONNECTED
;
sock
->
state
&=
~
FD_CONNECT
;
if
(
!
send_len
)
return
1
;
...
...
@@ -1866,11 +1885,11 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
if
(
how
!=
SD_SEND
)
{
sock
->
state
&=
~
FD_READ
;
sock
->
rd_shutdown
=
1
;
}
if
(
how
!=
SD_RECEIVE
)
{
sock
->
state
&=
~
FD_WRITE
;
sock
->
wr_shutdown
=
1
;
if
(
list_empty
(
&
sock
->
write_q
.
queue
))
shutdown
(
unix_fd
,
SHUT_WR
);
else
...
...
@@ -2462,8 +2481,7 @@ DECL_HANDLER(recv_socket)
status
=
STATUS_PENDING
;
}
/* are we shut down? */
if
(
status
==
STATUS_PENDING
&&
!
(
sock
->
state
&
FD_READ
))
status
=
STATUS_PIPE_DISCONNECTED
;
if
(
status
==
STATUS_PENDING
&&
sock
->
rd_shutdown
)
status
=
STATUS_PIPE_DISCONNECTED
;
sock
->
pending_events
&=
~
(
req
->
oob
?
FD_OOB
:
FD_READ
);
sock
->
reported_events
&=
~
(
req
->
oob
?
FD_OOB
:
FD_READ
);
...
...
@@ -2567,8 +2585,7 @@ DECL_HANDLER(send_socket)
status
=
STATUS_PENDING
;
}
/* are we shut down? */
if
(
status
==
STATUS_PENDING
&&
!
(
sock
->
state
&
FD_WRITE
))
status
=
STATUS_PIPE_DISCONNECTED
;
if
(
status
==
STATUS_PENDING
&&
sock
->
wr_shutdown
)
status
=
STATUS_PIPE_DISCONNECTED
;
if
((
async
=
create_request_async
(
fd
,
get_fd_comp_flags
(
fd
),
&
req
->
async
)))
{
...
...
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