1
0
Эх сурвалжийг харах

!318 修正pipe自动名字产生机制及修正pipe在注册设备时失败时未detach mutex问题
Merge pull request !318 from jesven/fix_pipe

bernard 4 жил өмнө
parent
commit
1481501b8a

+ 4 - 0
components/drivers/Kconfig

@@ -4,6 +4,10 @@ config RT_USING_DEVICE_IPC
     bool "Using device drivers IPC"
     default y
 
+config RT_UNAMED_PIPE_NUMBER
+    int "The number of unamed pipe"
+    default 64
+
 if RT_USING_DEVICE_IPC
     config RT_PIPE_BUFSZ
         int "Set pipe buffer size"

+ 3 - 0
components/drivers/include/ipc/pipe.h

@@ -25,6 +25,9 @@ struct rt_pipe_device
 {
     struct rt_device parent;
     rt_bool_t is_named;
+#ifdef RT_USING_POSIX
+    int pipeno; /* for unamed pipe */
+#endif
 
     /* ring buffer in pipe device */
     struct rt_ringbuffer *fifo;

+ 41 - 2
components/drivers/src/pipe.c

@@ -16,6 +16,28 @@
 #include <dfs_file.h>
 #include <dfs_posix.h>
 #include <dfs_poll.h>
+#include <resource_id.h>
+
+/* check RT_UNAMED_PIPE_NUMBER */
+
+#ifndef RT_UNAMED_PIPE_NUMBER
+#define RT_UNAMED_PIPE_NUMBER 64
+#endif
+
+#define BITS(x) _BITS(x)
+#define _BITS(x) (sizeof(#x) - 1)
+
+struct check_rt_unamed_pipe_number
+{
+    /* -4 for "pipe" prefix */
+    /* -1 for '\0' postfix */
+    char _check[RT_NAME_MAX - 4 - 1 - BITS(RT_UNAMED_PIPE_NUMBER)];
+};
+
+/* check end */
+
+static void *resoure_id[RT_UNAMED_PIPE_NUMBER];
+static resource_id_t id_mgr = RESOURCE_ID_INIT(RT_UNAMED_PIPE_NUMBER, resoure_id);
 
 static int pipe_fops_open(struct dfs_fd *fd)
 {
@@ -399,6 +421,9 @@ rt_pipe_t *rt_pipe_create(const char *name, int bufsz)
 
     rt_memset(pipe, 0, sizeof(rt_pipe_t));
     pipe->is_named = RT_TRUE; /* initialize as a named pipe */
+#ifdef RT_USING_POSIX
+    pipe->pipeno = -1;
+#endif
     rt_mutex_init(&pipe->lock, name, RT_IPC_FLAG_FIFO);
     rt_wqueue_init(&pipe->reader_queue);
     rt_wqueue_init(&pipe->writer_queue);
@@ -424,6 +449,10 @@ rt_pipe_t *rt_pipe_create(const char *name, int bufsz)
 
     if (rt_device_register(&pipe->parent, name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE) != 0)
     {
+        rt_mutex_detach(&pipe->lock);
+#ifdef RT_USING_POSIX
+        resource_id_put(&id_mgr, pipe->pipeno);
+#endif
         rt_free(pipe);
         return RT_NULL;
     }
@@ -449,6 +478,9 @@ int rt_pipe_delete(const char *name)
             pipe = (rt_pipe_t *)device;
 
             rt_mutex_detach(&pipe->lock);
+#ifdef RT_USING_POSIX
+            resource_id_put(&id_mgr, pipe->pipeno);
+#endif
             rt_device_unregister(device);
 
             /* close fifo ringbuffer */
@@ -478,17 +510,24 @@ int pipe(int fildes[2])
     rt_pipe_t *pipe;
     char dname[8];
     char dev_name[32];
-    static int pipeno = 0;
+    int pipeno = 0;
 
-    rt_snprintf(dname, sizeof(dname), "pipe%d", pipeno++);
+    pipeno = resource_id_get(&id_mgr);
+    if (pipeno == -1)
+    {
+        return -1;
+    }
+    rt_snprintf(dname, sizeof(dname), "pipe%d", pipeno);
 
     pipe = rt_pipe_create(dname, PIPE_BUFSZ);
     if (pipe == RT_NULL)
     {
+        resource_id_put(&id_mgr, pipeno);
         return -1;
     }
 
     pipe->is_named = RT_FALSE; /* unamed pipe */
+    pipe->pipeno = pipeno;
     rt_snprintf(dev_name, sizeof(dev_name), "/dev/%s", dname);
     fildes[0] = open(dev_name, O_RDONLY, 0);
     if (fildes[0] < 0)

+ 8 - 0
components/utilities/resource/SConscript

@@ -0,0 +1,8 @@
+from building import *
+
+cwd     = GetCurrentDir()
+src     = Glob('*.c')
+CPPPATH = [cwd]
+group   = DefineGroup('resource', src, depend = [], CPPPATH = CPPPATH)
+
+Return('group')

+ 62 - 0
components/utilities/resource/resource_id.c

@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-08-25     RT-Thread    First version
+ */
+#include <rthw.h>
+#include <rtthread.h>
+#include <resource_id.h>
+
+void resource_id_init(resource_id_t *mgr, int size, void **res)
+{
+    if (mgr)
+    {
+        mgr->size = size;
+        mgr->_res = res;
+        mgr->noused = 0;
+        mgr->_free = RT_NULL;
+    }
+}
+
+int resource_id_get(resource_id_t *mgr)
+{
+    rt_base_t level;
+    void **cur;
+
+    level = rt_hw_interrupt_disable();
+    if (mgr->_free)
+    {
+        cur = mgr->_free;
+        mgr->_free = (void **)*mgr->_free;
+        rt_hw_interrupt_enable(level);
+        return cur - mgr->_res;
+    }
+    else if (mgr->noused < mgr->size)
+    {
+        cur = &mgr->_res[mgr->noused++];
+        rt_hw_interrupt_enable(level);
+        return cur - mgr->_res;
+    }
+    rt_hw_interrupt_enable(level);
+    return -1;
+}
+
+void resource_id_put(resource_id_t *mgr, int no)
+{
+    rt_base_t level;
+    void **cur;
+
+    if (no >= 0 && no < mgr->size)
+    {
+        level = rt_hw_interrupt_disable();
+        cur = &mgr->_res[no];
+        *cur = (void *)mgr->_free;
+        mgr->_free = cur;
+        rt_hw_interrupt_enable(level);
+    }
+}
+

+ 31 - 0
components/utilities/resource/resource_id.h

@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-08-25     RT-Thread    First version
+ */
+
+#ifndef  RESOURCE_ID_H__
+#define  RESOURCE_ID_H__
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#define RESOURCE_ID_INIT(size, pool)  {size, pool, 0, RT_NULL}
+
+typedef struct
+{
+    int size;
+    void **_res;
+    int noused;
+    void **_free;
+} resource_id_t;
+
+void resource_id_init(resource_id_t *mgr, int size, void **res);
+int resource_id_get(resource_id_t *mgr);
+void resource_id_put(resource_id_t *mgr, int no);
+
+#endif  /*RESOURCE_ID_H__*/