mirror of
https://github.com/apache/nuttx.git
synced 2026-06-02 01:21:26 +08:00
net: add poll lock for local socket poll
net_lock/unlock is a big lock and repleace it to internal pool lock to avoid the priority inversion problem. Signed-off-by: zhangyuan21 <zhangyuan21@xiaomi.com> Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
This commit is contained in:
committed by
Alin Jerpelea
parent
904266ab23
commit
114d641f4a
@@ -132,6 +132,7 @@ struct local_conn_s
|
|||||||
#endif /* CONFIG_NET_LOCAL_SCM */
|
#endif /* CONFIG_NET_LOCAL_SCM */
|
||||||
|
|
||||||
mutex_t lc_sendlock; /* Make sending multi-thread safe */
|
mutex_t lc_sendlock; /* Make sending multi-thread safe */
|
||||||
|
mutex_t lc_polllock; /* Lock for net poll */
|
||||||
|
|
||||||
#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 */
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ FAR struct local_conn_s *local_alloc(void)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
nxmutex_init(&conn->lc_sendlock);
|
nxmutex_init(&conn->lc_sendlock);
|
||||||
|
nxmutex_init(&conn->lc_polllock);
|
||||||
|
|
||||||
#ifdef CONFIG_NET_LOCAL_SCM
|
#ifdef CONFIG_NET_LOCAL_SCM
|
||||||
conn->lc_cred.pid = nxsched_getpid();
|
conn->lc_cred.pid = nxsched_getpid();
|
||||||
@@ -217,6 +218,7 @@ void local_free(FAR struct local_conn_s *conn)
|
|||||||
/* Destory sem associated with the connection */
|
/* Destory sem associated with the connection */
|
||||||
|
|
||||||
nxmutex_destroy(&conn->lc_sendlock);
|
nxmutex_destroy(&conn->lc_sendlock);
|
||||||
|
nxmutex_destroy(&conn->lc_polllock);
|
||||||
|
|
||||||
/* And free the connection structure */
|
/* And free the connection structure */
|
||||||
|
|
||||||
|
|||||||
+16
-13
@@ -50,13 +50,14 @@ static int local_event_pollsetup(FAR struct local_conn_s *conn,
|
|||||||
int ret = OK;
|
int ret = OK;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
net_lock();
|
|
||||||
if (setup)
|
if (setup)
|
||||||
{
|
{
|
||||||
/* This is a request to set up the poll. Find an available
|
/* This is a request to set up the poll. Find an available
|
||||||
* slot for the poll structure reference
|
* slot for the poll structure reference
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
nxmutex_lock(&conn->lc_polllock);
|
||||||
|
|
||||||
for (i = 0; i < LOCAL_NPOLLWAITERS; i++)
|
for (i = 0; i < LOCAL_NPOLLWAITERS; i++)
|
||||||
{
|
{
|
||||||
/* Find an available slot */
|
/* Find an available slot */
|
||||||
@@ -71,11 +72,12 @@ static int local_event_pollsetup(FAR struct local_conn_s *conn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nxmutex_unlock(&conn->lc_polllock);
|
||||||
|
|
||||||
if (i >= LOCAL_NPOLLWAITERS)
|
if (i >= LOCAL_NPOLLWAITERS)
|
||||||
{
|
{
|
||||||
fds->priv = NULL;
|
fds->priv = NULL;
|
||||||
ret = -EBUSY;
|
return -EBUSY;
|
||||||
goto errout;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
eventset = 0;
|
eventset = 0;
|
||||||
@@ -93,20 +95,19 @@ static int local_event_pollsetup(FAR struct local_conn_s *conn,
|
|||||||
|
|
||||||
struct pollfd **slot = (struct pollfd **)fds->priv;
|
struct pollfd **slot = (struct pollfd **)fds->priv;
|
||||||
|
|
||||||
if (!slot)
|
nxmutex_lock(&conn->lc_polllock);
|
||||||
{
|
|
||||||
ret = -EIO;
|
|
||||||
goto errout;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove all memory of the poll setup */
|
/* Remove all memory of the poll setup */
|
||||||
|
|
||||||
|
if (slot != NULL)
|
||||||
|
{
|
||||||
*slot = NULL;
|
*slot = NULL;
|
||||||
fds->priv = NULL;
|
fds->priv = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
errout:
|
nxmutex_unlock(&conn->lc_polllock);
|
||||||
net_unlock();
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +136,9 @@ void local_event_pollnotify(FAR struct local_conn_s *conn,
|
|||||||
pollevent_t eventset)
|
pollevent_t eventset)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_NET_LOCAL_STREAM
|
#ifdef CONFIG_NET_LOCAL_STREAM
|
||||||
|
nxmutex_lock(&conn->lc_polllock);
|
||||||
poll_notify(conn->lc_event_fds, LOCAL_NPOLLWAITERS, eventset);
|
poll_notify(conn->lc_event_fds, LOCAL_NPOLLWAITERS, eventset);
|
||||||
|
nxmutex_unlock(&conn->lc_polllock);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,7 +200,7 @@ int local_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds)
|
|||||||
|
|
||||||
/* Find shadow pollfds. */
|
/* Find shadow pollfds. */
|
||||||
|
|
||||||
net_lock();
|
nxmutex_lock(&conn->lc_polllock);
|
||||||
|
|
||||||
shadowfds = conn->lc_inout_fds;
|
shadowfds = conn->lc_inout_fds;
|
||||||
while (shadowfds->fd != 0)
|
while (shadowfds->fd != 0)
|
||||||
@@ -205,7 +208,7 @@ int local_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds)
|
|||||||
shadowfds += 2;
|
shadowfds += 2;
|
||||||
if (shadowfds >= &conn->lc_inout_fds[2*LOCAL_NPOLLWAITERS])
|
if (shadowfds >= &conn->lc_inout_fds[2*LOCAL_NPOLLWAITERS])
|
||||||
{
|
{
|
||||||
net_unlock();
|
nxmutex_unlock(&conn->lc_polllock);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -222,7 +225,7 @@ int local_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds)
|
|||||||
shadowfds[1].arg = fds;
|
shadowfds[1].arg = fds;
|
||||||
shadowfds[1].events &= ~POLLIN;
|
shadowfds[1].events &= ~POLLIN;
|
||||||
|
|
||||||
net_unlock();
|
nxmutex_unlock(&conn->lc_polllock);
|
||||||
|
|
||||||
/* Setup poll for both shadow pollfds. */
|
/* Setup poll for both shadow pollfds. */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user