net/local:Make local send multi-thread safe
Signed-off-by: 田昕 <tianxin7@xiaomi.com>
This commit is contained in:
parent
c4bed9eae9
commit
20b9cc37d5
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue