diff --git a/net/local/local.h b/net/local/local.h index 9e060761f3..83f70c4320 100644 --- a/net/local/local.h +++ b/net/local/local.h @@ -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 */ diff --git a/net/local/local_conn.c b/net/local/local_conn.c index c17ca01b48..eaa391c098 100644 --- a/net/local/local_conn.c +++ b/net/local/local_conn.c @@ -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 */ diff --git a/net/local/local_netpoll.c b/net/local/local_netpoll.c index c519658639..83f50d6bef 100644 --- a/net/local/local_netpoll.c +++ b/net/local/local_netpoll.c @@ -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. */