add mutext to protect fdset

Signed-off-by: Huawei Xie <huawei.xie at intel.com>
---
 lib/librte_vhost/vhost_user/fd_man.c         | 39 +++++++++++++++++++++++-----
 lib/librte_vhost/vhost_user/fd_man.h         |  2 ++
 lib/librte_vhost/vhost_user/vhost-net-user.c | 19 +++++++++-----
 3 files changed, 48 insertions(+), 12 deletions(-)

diff --git a/lib/librte_vhost/vhost_user/fd_man.c 
b/lib/librte_vhost/vhost_user/fd_man.c
index 929fbc3..e86615d 100644
--- a/lib/librte_vhost/vhost_user/fd_man.c
+++ b/lib/librte_vhost/vhost_user/fd_man.c
@@ -145,6 +145,8 @@ fdset_add(struct fdset *pfdset, int fd, fd_cb rcb, fd_cb 
wcb, void *dat)
        if (pfdset == NULL || fd == -1)
                return -1;

+       pthread_mutex_lock(&pfdset->fd_mutex);
+
        /* Find a free slot in the list. */
        i = fdset_find_free_slot(pfdset);
        if (i == -1)
@@ -153,6 +155,8 @@ fdset_add(struct fdset *pfdset, int fd, fd_cb rcb, fd_cb 
wcb, void *dat)
        fdset_add_fd(pfdset, i, fd, rcb, wcb, dat);
        pfdset->num++;

+       pthread_mutex_unlock(&pfdset->fd_mutex);
+
        return 0;
 }

@@ -164,12 +168,19 @@ fdset_del(struct fdset *pfdset, int fd)
 {
        int i;

+       if (pfdset == NULL || fd == -1)
+               return;
+
+       pthread_mutex_lock(&pfdset->fd_mutex);
+
        i = fdset_find_fd(pfdset, fd);
        if (i != -1 && fd != -1) {
                pfdset->fd[i].fd = -1;
                pfdset->fd[i].rcb = pfdset->fd[i].wcb = NULL;
                pfdset->num--;
        }
+
+       pthread_mutex_unlock(&pfdset->fd_mutex);
 }

 /**
@@ -183,6 +194,9 @@ fdset_event_dispatch(struct fdset *pfdset)
        int i, maxfds;
        struct fdentry *pfdentry;
        int num = MAX_FDS;
+       fd_cb rcb, wcb;
+       void *dat;
+       int fd;

        if (pfdset == NULL)
                return;
@@ -190,18 +204,31 @@ fdset_event_dispatch(struct fdset *pfdset)
        while (1) {
                FD_ZERO(&rfds);
                FD_ZERO(&wfds);
+               pthread_mutex_lock(&pfdset->fd_mutex);
+
                maxfds = fdset_fill(&rfds, &wfds, pfdset);
-               if (maxfds == -1)
-                       return;
+               if (maxfds == -1) {
+                       pthread_mutex_unlock(&pfdset->fd_mutex);
+                       sleep(1);
+                       continue;
+               }
+
+               pthread_mutex_unlock(&pfdset->fd_mutex);

                select(maxfds + 1, &rfds, &wfds, NULL, NULL);

                for (i = 0; i < num; i++) {
+                       pthread_mutex_lock(&pfdset->fd_mutex);
                        pfdentry = &pfdset->fd[i];
-                       if (pfdentry->fd >= 0 && FD_ISSET(pfdentry->fd, &rfds) 
&& pfdentry->rcb)
-                               pfdentry->rcb(pfdentry->fd, pfdentry->dat);
-                       if (pfdentry->fd >= 0 && FD_ISSET(pfdentry->fd, &wfds) 
&& pfdentry->wcb)
-                               pfdentry->wcb(pfdentry->fd, pfdentry->dat);
+                       fd = pfdentry->fd;
+                       rcb = pfdentry->rcb;
+                       wcb = pfdentry->wcb;
+                       dat = pfdentry->dat;
+                       pthread_mutex_unlock(&pfdset->fd_mutex);
+                       if (fd >= 0 && FD_ISSET(fd, &rfds) && rcb)
+                               rcb(fd, dat);
+                       if (fd >= 0 && FD_ISSET(fd, &wfds) && wcb)
+                               wcb(fd, dat);
                }
        }
 }
diff --git a/lib/librte_vhost/vhost_user/fd_man.h 
b/lib/librte_vhost/vhost_user/fd_man.h
index 26b4619..4ebae57 100644
--- a/lib/librte_vhost/vhost_user/fd_man.h
+++ b/lib/librte_vhost/vhost_user/fd_man.h
@@ -34,6 +34,7 @@
 #ifndef _FD_MAN_H_
 #define _FD_MAN_H_
 #include <stdint.h>
+#include <pthread.h>

 #define MAX_FDS 1024

@@ -48,6 +49,7 @@ struct fdentry {

 struct fdset {
        struct fdentry fd[MAX_FDS];
+       pthread_mutex_t fd_mutex;
        int num;        /* current fd number of this fdset */
 };

diff --git a/lib/librte_vhost/vhost_user/vhost-net-user.c 
b/lib/librte_vhost/vhost_user/vhost-net-user.c
index 44ef398..e6df8a8 100644
--- a/lib/librte_vhost/vhost_user/vhost-net-user.c
+++ b/lib/librte_vhost/vhost_user/vhost-net-user.c
@@ -41,6 +41,7 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <errno.h>
+#include <pthread.h>

 #include <rte_log.h>
 #include <rte_virtio_net.h>
@@ -60,10 +61,18 @@ struct connfd_ctx {
 };

 #define MAX_VHOST_SERVER 1024
-static struct {
+struct _vhost_server {
        struct vhost_server *server[MAX_VHOST_SERVER];
-       struct fdset fdset;     /**< The fd list this vhost server manages. */
-} g_vhost_server;
+       struct fdset fdset;
+};
+
+static struct _vhost_server g_vhost_server = {
+       .fdset = {
+               .fd = { [0 ... MAX_FDS - 1] = {-1, NULL, NULL, NULL} },
+               .fd_mutex = PTHREAD_MUTEX_INITIALIZER,
+               .num = 0
+       },
+};

 static int vserver_idx;

@@ -423,10 +432,8 @@ rte_vhost_driver_register(const char *path)
 {
        struct vhost_server *vserver;

-       if (vserver_idx == 0) {
-               fdset_init(&g_vhost_server.fdset);
+       if (vserver_idx == 0)
                ops = get_virtio_net_callbacks();
-       }
        if (vserver_idx == MAX_VHOST_SERVER)
                return -1;

-- 
1.8.1.4

Reply via email to