| 4054 | } |
| 4055 | |
| 4056 | void |
| 4057 | soisdisconnected(struct socket *so) |
| 4058 | { |
| 4059 | |
| 4060 | SOCK_LOCK(so); |
| 4061 | |
| 4062 | /* |
| 4063 | * There is at least one reader of so_state that does not |
| 4064 | * acquire socket lock, namely soreceive_generic(). Ensure |
| 4065 | * that it never sees all flags that track connection status |
| 4066 | * cleared, by ordering the update with a barrier semantic of |
| 4067 | * our release thread fence. |
| 4068 | */ |
| 4069 | so->so_state |= SS_ISDISCONNECTED; |
| 4070 | atomic_thread_fence_rel(); |
| 4071 | so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING); |
| 4072 | |
| 4073 | if (!SOLISTENING(so)) { |
| 4074 | SOCK_UNLOCK(so); |
| 4075 | SOCKBUF_LOCK(&so->so_rcv); |
| 4076 | socantrcvmore_locked(so); |
| 4077 | SOCKBUF_LOCK(&so->so_snd); |
| 4078 | sbdrop_locked(&so->so_snd, sbused(&so->so_snd)); |
| 4079 | socantsendmore_locked(so); |
| 4080 | } else |
| 4081 | SOCK_UNLOCK(so); |
| 4082 | wakeup(&so->so_timeo); |
| 4083 | } |
| 4084 | |
| 4085 | /* |
| 4086 | * Make a copy of a sockaddr in a malloced buffer of type M_SONAME. |
no test coverage detected