usrsock/recv: guarantee all data is received before close

adjust the close sequence to avoid data discard

Signed-off-by: chao.an <anchao@xiaomi.com>
This commit is contained in:
chao.an 2021-03-18 22:08:44 +08:00 committed by Masayuki Ishikawa
parent 8fd64854f5
commit e506b2a52c
2 changed files with 19 additions and 18 deletions

View File

@ -99,16 +99,6 @@ int usrsock_event(FAR struct usrsock_conn_s *conn, uint16_t events)
conn->state = USRSOCK_CONN_STATE_ABORTED; conn->state = USRSOCK_CONN_STATE_ABORTED;
} }
if (events & USRSOCK_EVENT_REMOTE_CLOSED)
{
/* After reception of remote close event, clear input/output flags. */
conn->flags &= ~(USRSOCK_EVENT_SENDTO_READY |
USRSOCK_EVENT_RECVFROM_AVAIL);
conn->flags |= USRSOCK_EVENT_REMOTE_CLOSED;
}
if ((conn->state == USRSOCK_CONN_STATE_READY || if ((conn->state == USRSOCK_CONN_STATE_READY ||
conn->state == USRSOCK_CONN_STATE_CONNECTING) && conn->state == USRSOCK_CONN_STATE_CONNECTING) &&
!(conn->flags & USRSOCK_EVENT_REMOTE_CLOSED)) !(conn->flags & USRSOCK_EVENT_REMOTE_CLOSED))
@ -124,6 +114,15 @@ int usrsock_event(FAR struct usrsock_conn_s *conn, uint16_t events)
} }
} }
if (events & USRSOCK_EVENT_REMOTE_CLOSED)
{
/* After reception of remote close event, clear input flags. */
conn->flags &= ~USRSOCK_EVENT_SENDTO_READY;
conn->flags |= USRSOCK_EVENT_REMOTE_CLOSED;
}
/* Send events to callbacks */ /* Send events to callbacks */
devif_conn_event(NULL, conn, events, conn->list); devif_conn_event(NULL, conn, events, conn->list);

View File

@ -119,11 +119,11 @@ static uint16_t recvfrom_event(FAR struct net_driver_s *dev,
nxsem_post(&pstate->reqstate.recvsem); nxsem_post(&pstate->reqstate.recvsem);
} }
else if (flags & USRSOCK_EVENT_REMOTE_CLOSED) else if (flags & USRSOCK_EVENT_RECVFROM_AVAIL)
{ {
ninfo("remote closed.\n"); ninfo("recvfrom avail.\n");
pstate->reqstate.result = -EPIPE; flags &= ~USRSOCK_EVENT_RECVFROM_AVAIL;
/* Stop further callbacks */ /* Stop further callbacks */
@ -135,11 +135,11 @@ static uint16_t recvfrom_event(FAR struct net_driver_s *dev,
nxsem_post(&pstate->reqstate.recvsem); nxsem_post(&pstate->reqstate.recvsem);
} }
else if (flags & USRSOCK_EVENT_RECVFROM_AVAIL) else if (flags & USRSOCK_EVENT_REMOTE_CLOSED)
{ {
ninfo("recvfrom avail.\n"); ninfo("remote closed.\n");
flags &= ~USRSOCK_EVENT_RECVFROM_AVAIL; pstate->reqstate.result = -EPIPE;
/* Stop further callbacks */ /* Stop further callbacks */
@ -304,7 +304,8 @@ ssize_t usrsock_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
{ {
/* Check if remote end has closed connection. */ /* Check if remote end has closed connection. */
if (conn->flags & USRSOCK_EVENT_REMOTE_CLOSED) if (conn->flags & USRSOCK_EVENT_REMOTE_CLOSED &&
!(conn->flags & USRSOCK_EVENT_RECVFROM_AVAIL))
{ {
ninfo("usockid=%d; remote closed (EOF).\n", conn->usockid); ninfo("usockid=%d; remote closed (EOF).\n", conn->usockid);
@ -378,7 +379,8 @@ ssize_t usrsock_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
/* Did remote disconnect? */ /* Did remote disconnect? */
if (conn->flags & USRSOCK_EVENT_REMOTE_CLOSED) if (conn->flags & USRSOCK_EVENT_REMOTE_CLOSED &&
!(conn->flags & USRSOCK_EVENT_RECVFROM_AVAIL))
{ {
ret = 0; ret = 0;
goto errout_unlock; goto errout_unlock;