Fix r361037.
Reorder flag manipulations and use barrier to ensure that the program order is followed by compiler and CPU, for unlocked reader of so_state. In collaboration with: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D24842
This commit is contained in:
parent
134e17798c
commit
0532a7a2df
@ -4016,8 +4016,17 @@ soisdisconnected(struct socket *so)
|
|||||||
{
|
{
|
||||||
|
|
||||||
SOCK_LOCK(so);
|
SOCK_LOCK(so);
|
||||||
so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
|
|
||||||
|
/*
|
||||||
|
* There is at least one reader of so_state that does not
|
||||||
|
* acquire socket lock, namely soreceive_generic(). Ensure
|
||||||
|
* that it never sees all flags that track connection status
|
||||||
|
* cleared, by ordering the update with a barrier semantic of
|
||||||
|
* our release thread fence.
|
||||||
|
*/
|
||||||
so->so_state |= SS_ISDISCONNECTED;
|
so->so_state |= SS_ISDISCONNECTED;
|
||||||
|
atomic_thread_fence_rel();
|
||||||
|
so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
|
||||||
|
|
||||||
if (!SOLISTENING(so)) {
|
if (!SOLISTENING(so)) {
|
||||||
SOCK_UNLOCK(so);
|
SOCK_UNLOCK(so);
|
||||||
|
Loading…
Reference in New Issue
Block a user