diff --git a/components/drivers/include/ipc/pipe.h b/components/drivers/include/ipc/pipe.h index 338063ace81a029ec0a4709caf9f77d25454c341..2545e41c94225cbb3aa2110f851afd18bb55c799 100644 --- a/components/drivers/include/ipc/pipe.h +++ b/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; }; diff --git a/components/drivers/src/pipe.c b/components/drivers/src/pipe.c index 284104511bd1bade226db82cd59355c30d8aaf86..91df5ddcf44b6303a6de33501f285f60e371ffa8 100644 --- a/components/drivers/src/pipe.c +++ b/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; diff --git a/components/lwp/lwp_syscall.c b/components/lwp/lwp_syscall.c index a9038186d067e808beffbe0a8437ddc5c1120c83..3d6444c81269cb8932a8fd72e9c3c330f66a692d 100644 --- a/components/lwp/lwp_syscall.c +++ b/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();