From 20b9cc37d5923949c5dd024b96a547e018232956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=94=B0=E6=98=95?= Date: Mon, 8 Aug 2022 18:20:41 +0800 Subject: [PATCH] net/local:Make local send multi-thread safe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 田昕 --- net/local/local.h | 2 ++ net/local/local_conn.c | 10 ++++++++++ net/local/local_sendmsg.c | 23 +++++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/net/local/local.h b/net/local/local.h index 9af3a5139d..909dfc2659 100644 --- a/net/local/local.h +++ b/net/local/local.h @@ -141,6 +141,8 @@ struct local_conn_s lc_cfps[LOCAL_NCONTROLFDS]; /* Socket message control filep */ #endif /* CONFIG_NET_LOCAL_SCM */ + sem_t lc_sendsem; /* Make sending multi-thread safe */ + #ifdef CONFIG_NET_LOCAL_STREAM /* SOCK_STREAM fields common to both client and server */ diff --git a/net/local/local_conn.c b/net/local/local_conn.c index 2e343bb630..8524dded71 100644 --- a/net/local/local_conn.c +++ b/net/local/local_conn.c @@ -130,6 +130,12 @@ FAR struct local_conn_s *local_alloc(void) #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 */ net_lock(); @@ -210,6 +216,10 @@ void local_free(FAR struct local_conn_s *conn) nxsem_destroy(&conn->lc_donesem); #endif + /* Destory sem associated with the connection */ + + nxsem_destroy(&conn->lc_sendsem); + /* And free the connection structure */ kmm_free(conn); diff --git a/net/local/local_sendmsg.c b/net/local/local_sendmsg.c index 0ad0fb6d44..92a2804d01 100644 --- a/net/local/local_sendmsg.c +++ b/net/local/local_sendmsg.c @@ -196,7 +196,16 @@ static ssize_t local_send(FAR struct socket *psock, /* 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); + nxsem_post(&peer->lc_sendsem); } break; #endif /* CONFIG_NET_LOCAL_STREAM */ @@ -334,6 +343,16 @@ static ssize_t local_sendto(FAR struct socket *psock, 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 */ 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); } + nxsem_post(&conn->lc_sendsem); + +errout_with_sender: + /* Now we can close the write-only socket descriptor */ file_close(&conn->lc_outfile);