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;
}
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 ||
conn->state == USRSOCK_CONN_STATE_CONNECTING) &&
!(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 */
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);
}
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 */
@ -135,11 +135,11 @@ static uint16_t recvfrom_event(FAR struct net_driver_s *dev,
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 */
@ -304,7 +304,8 @@ ssize_t usrsock_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
{
/* 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);
@ -378,7 +379,8 @@ ssize_t usrsock_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
/* 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;
goto errout_unlock;