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:
parent
904266ab23
commit
114d641f4a
@ -132,6 +132,7 @@ struct local_conn_s
|
||||
#endif /* CONFIG_NET_LOCAL_SCM */
|
||||
|
||||
mutex_t lc_sendlock; /* Make sending multi-thread safe */
|
||||
mutex_t lc_polllock; /* Lock for net poll */
|
||||
|
||||
#ifdef CONFIG_NET_LOCAL_STREAM
|
||||
/* 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_polllock);
|
||||
|
||||
#ifdef CONFIG_NET_LOCAL_SCM
|
||||
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 */
|
||||
|
||||
nxmutex_destroy(&conn->lc_sendlock);
|
||||
nxmutex_destroy(&conn->lc_polllock);
|
||||
|
||||
/* And free the connection structure */
|
||||
|
||||
|
@ -50,13 +50,14 @@ static int local_event_pollsetup(FAR struct local_conn_s *conn,
|
||||
int ret = OK;
|
||||
int i;
|
||||
|
||||
net_lock();
|
||||
if (setup)
|
||||
{
|
||||
/* This is a request to set up the poll. Find an available
|
||||
* slot for the poll structure reference
|
||||
*/
|
||||
|
||||
nxmutex_lock(&conn->lc_polllock);
|
||||
|
||||
for (i = 0; i < LOCAL_NPOLLWAITERS; i++)
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
fds->priv = NULL;
|
||||
ret = -EBUSY;
|
||||
goto errout;
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
eventset = 0;
|
||||
@ -93,20 +95,19 @@ static int local_event_pollsetup(FAR struct local_conn_s *conn,
|
||||
|
||||
struct pollfd **slot = (struct pollfd **)fds->priv;
|
||||
|
||||
if (!slot)
|
||||
{
|
||||
ret = -EIO;
|
||||
goto errout;
|
||||
}
|
||||
nxmutex_lock(&conn->lc_polllock);
|
||||
|
||||
/* Remove all memory of the poll setup */
|
||||
|
||||
*slot = NULL;
|
||||
fds->priv = NULL;
|
||||
if (slot != NULL)
|
||||
{
|
||||
*slot = NULL;
|
||||
fds->priv = NULL;
|
||||
}
|
||||
|
||||
nxmutex_unlock(&conn->lc_polllock);
|
||||
}
|
||||
|
||||
errout:
|
||||
net_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -135,7 +136,9 @@ void local_event_pollnotify(FAR struct local_conn_s *conn,
|
||||
pollevent_t eventset)
|
||||
{
|
||||
#ifdef CONFIG_NET_LOCAL_STREAM
|
||||
nxmutex_lock(&conn->lc_polllock);
|
||||
poll_notify(conn->lc_event_fds, LOCAL_NPOLLWAITERS, eventset);
|
||||
nxmutex_unlock(&conn->lc_polllock);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -197,7 +200,7 @@ int local_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds)
|
||||
|
||||
/* Find shadow pollfds. */
|
||||
|
||||
net_lock();
|
||||
nxmutex_lock(&conn->lc_polllock);
|
||||
|
||||
shadowfds = conn->lc_inout_fds;
|
||||
while (shadowfds->fd != 0)
|
||||
@ -205,7 +208,7 @@ int local_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds)
|
||||
shadowfds += 2;
|
||||
if (shadowfds >= &conn->lc_inout_fds[2*LOCAL_NPOLLWAITERS])
|
||||
{
|
||||
net_unlock();
|
||||
nxmutex_unlock(&conn->lc_polllock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
@ -222,7 +225,7 @@ int local_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds)
|
||||
shadowfds[1].arg = fds;
|
||||
shadowfds[1].events &= ~POLLIN;
|
||||
|
||||
net_unlock();
|
||||
nxmutex_unlock(&conn->lc_polllock);
|
||||
|
||||
/* Setup poll for both shadow pollfds. */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user