فهرست منبع

Adapt rt_channel, increase the generality of some rt_channel functionality on dfs v2, and standardize signalfd (#8047)

zmq810150896 1 سال پیش
والد
کامیت
092b52ab24

+ 1 - 0
components/libc/compilers/common/include/dirent.h

@@ -28,6 +28,7 @@ extern "C" {
 #define FT_USER         3   /* user defined */
 #define FT_DEVICE       4   /* device */
 #define FT_SYMLINK      5   /* symbol link */
+#define FT_NONLOCK      6   /* non lock */
 
 #define DT_UNKNOWN      0x00
 #define DT_FIFO         0x01

+ 12 - 0
components/libc/posix/Kconfig

@@ -36,6 +36,18 @@ if RT_USING_POSIX_FS
             bool "Enable I/O Multiplexing epoll <sys/epoll.h>"
             select RT_USING_POSIX_POLL
             default n
+
+        config RT_USING_POSIX_SIGNALFD
+            bool "Enable Signalfd <sys/signalfd.h>"
+            select RT_USING_POSIX_POLL
+            default n
+
+        if RT_USING_POSIX_SIGNALFD
+            config RT_SIGNALFD_MAX_NUM
+                int "signaled The maximum number of concurrent firing signals"
+                range 1 20
+                default 10
+        endif
     endif
 
     config RT_USING_POSIX_SOCKET

+ 8 - 1
components/libc/posix/io/epoll/epoll.c

@@ -115,6 +115,9 @@ static int epoll_close(struct dfs_file *file)
 {
     struct rt_eventpoll *ep;
 
+    if (file->vnode->ref_count != 1)
+        return 0;
+
     if (file->vnode)
     {
         if (file->vnode->data)
@@ -552,7 +555,7 @@ static int epoll_do_ctl(int epfd, int op, int fd, struct epoll_event *event)
     if (epdf->vnode->data)
     {
         ep = epdf->vnode->data;
-
+        event->events  |= EPOLLERR | EPOLLHUP;
         rt_mutex_take(&ep->lock, RT_WAITING_FOREVER);
 
         switch (op)
@@ -576,6 +579,10 @@ static int epoll_do_ctl(int epfd, int op, int fd, struct epoll_event *event)
             rt_set_errno(-ret);
             ret = -1;
         }
+        else
+        {
+            ep->polling_thread = rt_thread_self();
+        }
 
         rt_mutex_release(&ep->lock);
     }

+ 6 - 3
components/libc/posix/io/eventfd/eventfd.c

@@ -61,8 +61,11 @@ static int eventfd_close(struct dfs_file *file)
 {
     struct eventfd_ctx *ctx = file->vnode->data;
 
-    rt_mutex_detach(&ctx->lock);
-    rt_free(ctx);
+    if (file->vnode->ref_count == 1)
+    {
+        rt_mutex_detach(&ctx->lock);
+        rt_free(ctx);
+    }
 
     return 0;
 }
@@ -219,7 +222,7 @@ static int rt_eventfd_create(struct dfs_file *df, unsigned int count, int flags)
         df->vnode = (struct dfs_vnode *)rt_malloc(sizeof(struct dfs_vnode));
         if (df->vnode)
         {
-            dfs_vnode_init(df->vnode, FT_REGULAR, &eventfd_fops);
+            dfs_vnode_init(df->vnode, FT_NONLOCK, &eventfd_fops);
             df->vnode->data = ctx;
             df->flags = flags;
         }

+ 54 - 22
components/libc/posix/io/signalfd/signalfd.c

@@ -19,7 +19,8 @@
 #include <poll.h>
 
 #define SIGNALFD_MUTEX_NAME "signalfd"
-#define SIGNALFD_SHART_MAX 10
+#define SIGINFO_MAX 10
+#define SIGNALFD_SHART_MAX RT_SIGNALFD_MAX_NUM
 
 static int is_head_init = 0;
 
@@ -27,8 +28,8 @@ struct rt_signalfd_ctx
 {
     sigset_t sigmask;
     struct rt_mutex lock;
-    siginfo_t info;
-    int tick;
+    siginfo_t info[SIGINFO_MAX];
+    int sig_num;
     rt_wqueue_t signalfd_queue;
     struct rt_lwp *lwp[SIGNALFD_SHART_MAX];
 };
@@ -81,10 +82,9 @@ static int signalfd_poll(struct dfs_file *file, struct rt_pollreq *req)
 
         rt_mutex_take(&sfd->lock, RT_WAITING_FOREVER);
 
-        if (sfd->tick)
+        if (sfd->sig_num)
             events |= POLLIN;
 
-        sfd->tick = 0;
         rt_mutex_release(&sfd->lock);
     }
 
@@ -97,30 +97,62 @@ static ssize_t signalfd_read(struct dfs_file *file, void *buf, size_t count)
 static ssize_t signalfd_read(struct dfs_file *file, void *buf, size_t count, off_t *pos)
 #endif
 {
-    struct rt_signalfd_ctx *sfd;
-    struct signalfd_siginfo *buffer;
+    struct rt_signalfd_ctx *sfd = RT_NULL;
+    struct signalfd_siginfo *buffer = RT_NULL;
+    int user_buf_num = 0;
+    int sig_num = 0;
+    int i = 0;
     rt_err_t ret = -1;
 
     if (sizeof(struct signalfd_siginfo) > count)
         return -1;
 
+    if (buf == RT_NULL)
+        return -1;
+
     buffer = (struct signalfd_siginfo *)buf;
+    user_buf_num = count / sizeof(struct signalfd_siginfo);
 
     if (file->vnode)
     {
         sfd = file->vnode->data;
 
         signalfd_add_notify(sfd);
+        if ((sfd->sig_num == 0) && (file->flags & O_NONBLOCK))
+        {
+            ret = -EAGAIN;
+        }
+        else
+        {
+            if (sfd->sig_num == 0)
+            {
+                rt_wqueue_wait(&sfd->signalfd_queue, 0, RT_WAITING_FOREVER);
+            }
 
-        rt_wqueue_wait(&sfd->signalfd_queue, 0, RT_WAITING_FOREVER);
-        rt_mutex_take(&sfd->lock, RT_WAITING_FOREVER);
-        sfd->tick = 1;
-        rt_mutex_release(&sfd->lock);
+            rt_mutex_take(&sfd->lock, RT_WAITING_FOREVER);
+            for (i = 0; i < sfd->sig_num; i++)
+            {
+                if (i < user_buf_num)
+                {
+                    memcpy(&buffer[i], &sfd->info[i], sizeof(struct signalfd_siginfo));
+                    sfd->sig_num -= 1;
+                    sig_num += 1;
+                }
+                else
+                {
+                    break;
+                }
+            }
 
-        buffer->ssi_signo = sfd->info.si_signo;
-        buffer->ssi_code = sfd->info.si_code;
+            for (int j = 0; j < sfd->sig_num; j ++)
+            {
+                memcpy(&sfd->info[j], &sfd->info[i ++], sizeof(struct signalfd_siginfo));
+            }
 
-        ret = sizeof(struct signalfd_siginfo);
+            rt_mutex_release(&sfd->lock);
+
+            ret = sizeof(struct signalfd_siginfo) * sig_num;
+        }
     }
 
     return ret;
@@ -134,16 +166,16 @@ static void signalfd_callback(rt_wqueue_t *signalfd_queue, int signum)
 
     if (sfd)
     {
-        for (int sig = 1; sig < NSIG; sig++)
+        if (sigismember(&sfd->sigmask, signum))
         {
-            if (sigismember(&sfd->sigmask, signum))
+            rt_mutex_take(&sfd->lock, RT_WAITING_FOREVER);
+            if (sfd->sig_num < SIGINFO_MAX)
             {
-                rt_mutex_take(&sfd->lock, RT_WAITING_FOREVER);
-                sfd->tick = 1;
-                sfd->info.si_signo = signum;
-                rt_mutex_release(&sfd->lock);
-                rt_wqueue_wakeup(signalfd_queue, (void*)POLLIN);
+                sfd->info[sfd->sig_num].si_signo = signum;
+                sfd->sig_num += 1;
             }
+            rt_mutex_release(&sfd->lock);
+            rt_wqueue_wakeup(signalfd_queue, (void*)POLLIN);
         }
     }
 }
@@ -249,7 +281,7 @@ static int signalfd_do(int fd, const sigset_t *mask, int flags)
                         ret = -1;
                     }
 
-                    sfd->tick = 0;
+                    sfd->sig_num = 0;
 
                     df->flags |= flags;
 

+ 18 - 6
components/lwp/lwp_ipc.c

@@ -1,11 +1,12 @@
 /*
- * Copyright (c) 2006-2020, RT-Thread Development Team
+ * Copyright (c) 2006-2023, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
  * Change Logs:
  * Date           Author       Notes
  * 2019-10-12     Jesven       first version
+ * 2023-09-16     zmq810150896 Increased versatility of some features on dfs v2
  */
 #include <rtthread.h>
 #include <rthw.h>
@@ -371,7 +372,7 @@ static void *_ipc_msg_get_file(int fd)
         return RT_NULL;
 
     d->vnode->ref_count++;
-    return (void *)d->vnode;
+    return (void *)d;
 }
 
 /**
@@ -381,7 +382,14 @@ static int _ipc_msg_fd_new(void *file)
 {
     int fd;
     struct dfs_file *d;
-    struct dfs_vnode *vnode = (struct dfs_vnode *)file;
+    struct dfs_file *df = RT_NULL;
+
+    if (file == RT_NULL)
+    {
+        return -1;
+    }
+
+    df = (struct dfs_file *)file;
 
     fd = fd_new();
     if (fd < 0)
@@ -397,11 +405,15 @@ static int _ipc_msg_fd_new(void *file)
     }
 
 #ifdef RT_USING_DFS_V2
-    d->fops = vnode->fops;
+    d->fops = df->fops;
+    d->mode = df->mode;
+    d->dentry = df->dentry;
 #endif
 
-    d->vnode = vnode;
-    d->flags = O_RDWR; /* set flags as read and write */
+    d->vnode = df->vnode;
+    d->flags = df->flags;
+    d->data = df->data;
+    d->magic = df->magic;
 
     return fd;
 }