Przeglądaj źródła

!523 fix_pipe
Merge pull request !523 from wsljy2021/fix_pipe

bernard 3 lat temu
rodzic
commit
711f63e743

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

@@ -35,6 +35,8 @@ struct rt_pipe_device
 
     rt_wqueue_t reader_queue;
     rt_wqueue_t writer_queue;
+    int writer;
+    int reader;
 
     struct rt_mutex lock;
 };

+ 26 - 1
components/drivers/src/pipe.c

@@ -52,6 +52,15 @@ static int pipe_fops_open(struct dfs_fd *fd)
 
     rt_mutex_take(&pipe->lock, RT_WAITING_FOREVER);
 
+    if ((fd->flags & O_RDONLY) == O_RDONLY)
+    {
+        pipe->reader = 1;
+    }
+
+    if ((fd->flags & O_WRONLY) == O_WRONLY)
+    {
+        pipe->writer = 1;
+    }
     if (fd->fnode->ref_count == 1)
     {
         pipe->fifo = rt_ringbuffer_create(pipe->bufsz);
@@ -82,6 +91,20 @@ static int pipe_fops_close(struct dfs_fd *fd)
     device = &pipe->parent;
     rt_mutex_take(&pipe->lock, RT_WAITING_FOREVER);
 
+    if ((fd->flags & O_RDONLY) == O_RDONLY)
+    {
+        pipe->reader = 0;
+    }
+
+    if ((fd->flags & O_WRONLY) == O_WRONLY)
+    {
+        pipe->writer = 0;
+        while (!rt_list_isempty(&pipe->reader_queue.waiting_list))
+        {
+            rt_wqueue_wakeup(&pipe->reader_queue, (void*)POLLIN);
+        }
+    }
+
     if (fd->fnode->ref_count == 1)
     {
         if (pipe->fifo != RT_NULL)
@@ -139,7 +162,7 @@ static int pipe_fops_read(struct dfs_fd *fd, void *buf, size_t count)
     {
         len = rt_ringbuffer_get(pipe->fifo, buf, count);
 
-        if (len > 0)
+        if (len > 0 || pipe->writer == 0)
         {
             break;
         }
@@ -427,6 +450,8 @@ rt_pipe_t *rt_pipe_create(const char *name, int bufsz)
     rt_mutex_init(&pipe->lock, name, RT_IPC_FLAG_FIFO);
     rt_wqueue_init(&pipe->reader_queue);
     rt_wqueue_init(&pipe->writer_queue);
+    pipe->writer = 0;
+    pipe->reader = 0;
 
     RT_ASSERT(bufsz < 0xFFFF);
     pipe->bufsz = bufsz;

+ 3 - 24
components/lwp/lwp_syscall.c

@@ -1590,40 +1590,19 @@ static int lwp_copy_files(struct rt_lwp *dst, struct rt_lwp *src)
     if (dst_fdt->fds)
     {
         struct dfs_fd *d_s;
-        struct dfs_fd *d_d;
         int i;
 
         dst_fdt->maxfd = src_fdt->maxfd;
 
         dfs_fd_lock();
-        /* copy stdio */
+        /* dup files */
         for (i = 0; i < src_fdt->maxfd; i++)
         {
             d_s = fdt_fd_get(src_fdt, i);
             if (d_s)
             {
-                dfs_fm_lock();
-                if (!d_s->fnode)
-                {
-                    dfs_fm_unlock();
-                    continue;
-                }
-                d_s->fnode->ref_count++;
-                dfs_fm_unlock();
-
-                /* alloc dfs_fd struct */
-                d_d = (struct dfs_fd *)rt_calloc(1, sizeof(struct dfs_fd));
-                if (!d_d)
-                {
-                    dfs_fd_unlock();
-                    return -1;
-                }
-                dst_fdt->fds[i] = d_d;
-                d_d->magic = d_s->magic;
-                d_d->ref_count = 1;
-                d_d->pos = d_s->pos;
-                d_d->fnode = d_s->fnode;
-                d_d->data = d_s->data;
+                dst_fdt->fds[i] = d_s;
+                d_s->ref_count++;
             }
         }
         dfs_fd_unlock();