diff --git a/components/libc/compilers/common/include/dirent.h b/components/libc/compilers/common/include/dirent.h index 857be6388b..f1a45d2986 100644 --- a/components/libc/compilers/common/include/dirent.h +++ b/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 diff --git a/components/libc/posix/Kconfig b/components/libc/posix/Kconfig index 847e8e4e70..a927897dfb 100644 --- a/components/libc/posix/Kconfig +++ b/components/libc/posix/Kconfig @@ -36,6 +36,18 @@ if RT_USING_POSIX_FS bool "Enable I/O Multiplexing epoll " select RT_USING_POSIX_POLL default n + + config RT_USING_POSIX_SIGNALFD + bool "Enable Signalfd " + 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 diff --git a/components/libc/posix/io/epoll/epoll.c b/components/libc/posix/io/epoll/epoll.c index 24d3e376a3..7c33d775a2 100644 --- a/components/libc/posix/io/epoll/epoll.c +++ b/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); } diff --git a/components/libc/posix/io/eventfd/eventfd.c b/components/libc/posix/io/eventfd/eventfd.c index b4dddc00f8..a2f0975128 100644 --- a/components/libc/posix/io/eventfd/eventfd.c +++ b/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; } diff --git a/components/libc/posix/io/signalfd/signalfd.c b/components/libc/posix/io/signalfd/signalfd.c index b7cb20dc44..735740fafc 100644 --- a/components/libc/posix/io/signalfd/signalfd.c +++ b/components/libc/posix/io/signalfd/signalfd.c @@ -19,7 +19,8 @@ #include #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; diff --git a/components/lwp/lwp_ipc.c b/components/lwp/lwp_ipc.c index 60e216565c..4536c9d6fa 100644 --- a/components/lwp/lwp_ipc.c +++ b/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 #include @@ -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; }