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);