net/local:Make local send multi-thread safe

Signed-off-by: 田昕 <tianxin7@xiaomi.com>
This commit is contained in:
田昕 2022-08-08 18:20:41 +08:00 committed by Xiang Xiao
parent c4bed9eae9
commit 20b9cc37d5
3 changed files with 35 additions and 0 deletions

View File

@ -141,6 +141,8 @@ struct local_conn_s
lc_cfps[LOCAL_NCONTROLFDS]; /* Socket message control filep */ lc_cfps[LOCAL_NCONTROLFDS]; /* Socket message control filep */
#endif /* CONFIG_NET_LOCAL_SCM */ #endif /* CONFIG_NET_LOCAL_SCM */
sem_t lc_sendsem; /* Make sending multi-thread safe */
#ifdef CONFIG_NET_LOCAL_STREAM #ifdef CONFIG_NET_LOCAL_STREAM
/* SOCK_STREAM fields common to both client and server */ /* SOCK_STREAM fields common to both client and server */

View File

@ -130,6 +130,12 @@ FAR struct local_conn_s *local_alloc(void)
#endif #endif
/* This semaphore is used for sending safely in multithread.
* Make sure data will not be garbled when multi-thread sends.
*/
nxsem_init(&conn->lc_sendsem, 0, 1);
/* Add the connection structure to the list of listeners */ /* Add the connection structure to the list of listeners */
net_lock(); net_lock();
@ -210,6 +216,10 @@ void local_free(FAR struct local_conn_s *conn)
nxsem_destroy(&conn->lc_donesem); nxsem_destroy(&conn->lc_donesem);
#endif #endif
/* Destory sem associated with the connection */
nxsem_destroy(&conn->lc_sendsem);
/* And free the connection structure */ /* And free the connection structure */
kmm_free(conn); kmm_free(conn);

View File

@ -196,7 +196,16 @@ static ssize_t local_send(FAR struct socket *psock,
/* Send the packet */ /* Send the packet */
ret = nxsem_wait_uninterruptible(&peer->lc_sendsem);
if (ret < 0)
{
/* May fail because the task was canceled. */
return ret;
}
ret = local_send_packet(&peer->lc_outfile, buf, len, false); ret = local_send_packet(&peer->lc_outfile, buf, len, false);
nxsem_post(&peer->lc_sendsem);
} }
break; break;
#endif /* CONFIG_NET_LOCAL_STREAM */ #endif /* CONFIG_NET_LOCAL_STREAM */
@ -334,6 +343,16 @@ static ssize_t local_sendto(FAR struct socket *psock,
goto errout_with_halfduplex; goto errout_with_halfduplex;
} }
/* Make sure that dgram is sent safely */
ret = nxsem_wait_uninterruptible(&conn->lc_sendsem);
if (ret < 0)
{
/* May fail because the task was canceled. */
goto errout_with_sender;
}
/* Send the packet */ /* Send the packet */
ret = local_send_packet(&conn->lc_outfile, buf, len, true); ret = local_send_packet(&conn->lc_outfile, buf, len, true);
@ -342,6 +361,10 @@ static ssize_t local_sendto(FAR struct socket *psock,
nerr("ERROR: Failed to send the packet: %zd\n", ret); nerr("ERROR: Failed to send the packet: %zd\n", ret);
} }
nxsem_post(&conn->lc_sendsem);
errout_with_sender:
/* Now we can close the write-only socket descriptor */ /* Now we can close the write-only socket descriptor */
file_close(&conn->lc_outfile); file_close(&conn->lc_outfile);