261 lines
8.8 KiB
Diff
261 lines
8.8 KiB
Diff
From 21425705a687706faa642e8b99a9c549d7bcaab6 Mon Sep 17 00:00:00 2001
|
|
From: yangchen <yangchen145@huawei.com>
|
|
Date: Thu, 2 Nov 2023 16:10:04 +0800
|
|
Subject: [PATCH] wrap: support select
|
|
|
|
---
|
|
src/lstack/api/lstack_epoll.c | 88 +++++++++++++++++++++++++
|
|
src/lstack/api/lstack_rtc_api.c | 7 ++
|
|
src/lstack/api/lstack_rtw_api.c | 5 ++
|
|
src/lstack/api/lstack_wrap.c | 19 ++++++
|
|
src/lstack/include/lstack_rtc_api.h | 2 +
|
|
src/lstack/include/lstack_rtw_api.h | 3 +
|
|
src/lstack/include/posix/lstack_epoll.h | 1 +
|
|
7 files changed, 125 insertions(+)
|
|
|
|
diff --git a/src/lstack/api/lstack_epoll.c b/src/lstack/api/lstack_epoll.c
|
|
index a711ae3..f2c4a8b 100644
|
|
--- a/src/lstack/api/lstack_epoll.c
|
|
+++ b/src/lstack/api/lstack_epoll.c
|
|
@@ -13,6 +13,7 @@
|
|
#include <string.h>
|
|
#include <securec.h>
|
|
#include <sys/epoll.h>
|
|
+#include <sys/select.h>
|
|
#include <time.h>
|
|
#include <poll.h>
|
|
#include <stdatomic.h>
|
|
@@ -870,3 +871,90 @@ int32_t lstack_poll(struct pollfd *fds, nfds_t nfds, int32_t timeout)
|
|
__atomic_store_n(&wakeup->in_wait, false, __ATOMIC_RELEASE);
|
|
return lwip_num + kernel_num;
|
|
}
|
|
+
|
|
+static void select_set_revent_fdset(struct pollfd *fds, nfds_t nfds, fd_set *eventfds, uint32_t event)
|
|
+{
|
|
+ FD_ZERO(eventfds);
|
|
+
|
|
+ /* Set the fd_set parameter based on the actual revents. */
|
|
+ for (int i = 0; i < nfds; i++) {
|
|
+ if (fds[i].revents & event) {
|
|
+ FD_SET(fds[i].fd, eventfds);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+static void fds_poll2select(struct pollfd *fds, nfds_t nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
|
|
+{
|
|
+ if (fds == NULL || nfds == 0) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (readfds) {
|
|
+ select_set_revent_fdset(fds, nfds, readfds, EPOLLIN);
|
|
+ }
|
|
+ if (writefds) {
|
|
+ select_set_revent_fdset(fds, nfds, writefds, EPOLLOUT);
|
|
+ }
|
|
+ if (exceptfds) {
|
|
+ select_set_revent_fdset(fds, nfds, exceptfds, EPOLLERR);
|
|
+ }
|
|
+}
|
|
+
|
|
+static inline int timeval_to_ms(struct timeval *timeval)
|
|
+{
|
|
+ if (timeval == NULL) {
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ return (timeval->tv_sec * 1000 + timeval->tv_usec / 1000);
|
|
+}
|
|
+
|
|
+static nfds_t fds_select2poll(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct pollfd **fds)
|
|
+{
|
|
+ struct pollfd pollfds[FD_SETSIZE] = { 0 };
|
|
+ nfds_t nfds = 0;
|
|
+
|
|
+ for (int i = 0; i < maxfd; i++) {
|
|
+ if (readfds && FD_ISSET(i, readfds)) {
|
|
+ pollfds[nfds].events = POLLIN;
|
|
+ }
|
|
+ if (writefds && FD_ISSET(i, writefds)) {
|
|
+ pollfds[nfds].events |= POLLOUT;
|
|
+ }
|
|
+ if (exceptfds && FD_ISSET(i, exceptfds)) {
|
|
+ pollfds[nfds].events |= POLLERR;
|
|
+ }
|
|
+ if (pollfds[nfds].events > 0) {
|
|
+ pollfds[nfds].fd = i;
|
|
+ nfds++;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ *fds = pollfds;
|
|
+ return nfds;
|
|
+}
|
|
+
|
|
+int lstack_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeval)
|
|
+{
|
|
+ if (maxfd == 0) {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ if (maxfd < 0 || maxfd > FD_SETSIZE || (readfds == NULL && writefds == NULL && exceptfds == NULL)) {
|
|
+ GAZELLE_RETURN(EINVAL);
|
|
+ }
|
|
+
|
|
+ /* Convert the select parameter to the poll parameter. */
|
|
+ struct pollfd *fds = NULL;
|
|
+ nfds_t nfds = fds_select2poll(maxfd, readfds, writefds, exceptfds, &fds);
|
|
+ int timeout = timeval_to_ms(timeval);
|
|
+
|
|
+ int event_num = lstack_poll(fds, nfds, timeout);
|
|
+
|
|
+ /* After poll, set select fd_set by fds.revents. */
|
|
+ fds_poll2select(fds, nfds, readfds, writefds, exceptfds);
|
|
+
|
|
+ return event_num;
|
|
+}
|
|
+
|
|
diff --git a/src/lstack/api/lstack_rtc_api.c b/src/lstack/api/lstack_rtc_api.c
|
|
index 059b518..5fad3e8 100644
|
|
--- a/src/lstack/api/lstack_rtc_api.c
|
|
+++ b/src/lstack/api/lstack_rtc_api.c
|
|
@@ -24,6 +24,13 @@
|
|
|
|
int rtc_poll(struct pollfd *fds, nfds_t nfds, int timeout)
|
|
{
|
|
+ LSTACK_LOG(ERR, LSTACK, "rtc_poll: rtc currently does not support poll\n");
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+int rtc_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
|
|
+{
|
|
+ LSTACK_LOG(ERR, LSTACK, "rtc_select: rtc currently does not support select\n");
|
|
return -1;
|
|
}
|
|
|
|
diff --git a/src/lstack/api/lstack_rtw_api.c b/src/lstack/api/lstack_rtw_api.c
|
|
index 7d14ffa..c524bf9 100644
|
|
--- a/src/lstack/api/lstack_rtw_api.c
|
|
+++ b/src/lstack/api/lstack_rtw_api.c
|
|
@@ -214,6 +214,11 @@ int rtw_poll(struct pollfd *fds, nfds_t nfds, int timeout)
|
|
return lstack_poll(fds, nfds, timeout);
|
|
}
|
|
|
|
+int rtw_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
|
|
+{
|
|
+ return lstack_select(nfds, readfds, writefds, exceptfds, timeout);
|
|
+}
|
|
+
|
|
int rtw_close(int s)
|
|
{
|
|
struct lwip_sock *sock = get_socket(s);
|
|
diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c
|
|
index a808ee8..5bad513 100644
|
|
--- a/src/lstack/api/lstack_wrap.c
|
|
+++ b/src/lstack/api/lstack_wrap.c
|
|
@@ -76,6 +76,7 @@ void wrap_api_init(void)
|
|
g_wrap_api->epoll_ctl_fn = rtc_epoll_ctl;
|
|
g_wrap_api->epoll_create1_fn = rtc_epoll_create1;
|
|
g_wrap_api->epoll_create_fn = rtc_epoll_create;
|
|
+ g_wrap_api->select_fn = rtc_select;
|
|
} else {
|
|
g_wrap_api->socket_fn = rtw_socket;
|
|
g_wrap_api->accept_fn = rtw_accept;
|
|
@@ -103,6 +104,7 @@ void wrap_api_init(void)
|
|
g_wrap_api->epoll_ctl_fn = rtw_epoll_ctl;
|
|
g_wrap_api->epoll_create1_fn = rtw_epoll_create1;
|
|
g_wrap_api->epoll_create_fn = rtw_epoll_create;
|
|
+ g_wrap_api->select_fn = rtw_select;
|
|
}
|
|
}
|
|
|
|
@@ -609,6 +611,15 @@ static int32_t do_sigaction(int32_t signum, const struct sigaction *act, struct
|
|
return lstack_sigaction(signum, act, oldact);
|
|
}
|
|
|
|
+static int32_t do_select(int32_t nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
|
|
+{
|
|
+ if (select_posix_path() == PATH_KERNEL) {
|
|
+ return posix_api->select_fn(nfds, readfds, writefds, exceptfds, timeout);
|
|
+ }
|
|
+
|
|
+ return g_wrap_api->select_fn(nfds, readfds, writefds, exceptfds, timeout);
|
|
+}
|
|
+
|
|
#define WRAP_VA_PARAM(_fd, _cmd, _lwip_fcntl, _fcntl_fn) \
|
|
do { \
|
|
unsigned long val; \
|
|
@@ -769,6 +780,10 @@ pid_t fork(void)
|
|
{
|
|
return lstack_fork();
|
|
}
|
|
+int32_t select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
|
|
+{
|
|
+ return do_select(nfds, readfds, writefds, exceptfds, timeout);
|
|
+}
|
|
|
|
/* --------------------------------------------------------
|
|
* ------- Compile mode replacement interface -----------
|
|
@@ -898,3 +913,7 @@ pid_t __wrap_fork(void)
|
|
{
|
|
return lstack_fork();
|
|
}
|
|
+int32_t __wrap_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
|
|
+{
|
|
+ return do_select(nfds, readfds, writefds, exceptfds, timeout);
|
|
+}
|
|
diff --git a/src/lstack/include/lstack_rtc_api.h b/src/lstack/include/lstack_rtc_api.h
|
|
index 0aff928..dd90e59 100644
|
|
--- a/src/lstack/include/lstack_rtc_api.h
|
|
+++ b/src/lstack/include/lstack_rtc_api.h
|
|
@@ -13,6 +13,7 @@
|
|
#ifndef _LSTACK_RTC_API_H_
|
|
#define _LSTACK_RTC_API_H_
|
|
#include <sys/epoll.h>
|
|
+#include <sys/select.h>
|
|
#include <sys/socket.h>
|
|
|
|
/* don't include lwip/sockets.h, conflict with sys/socket.h */
|
|
@@ -51,5 +52,6 @@ int rtc_close(int s);
|
|
int rtc_epoll_create(int flags);
|
|
int rtc_epoll_create1(int flags);
|
|
int rtc_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
|
|
+int rtc_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
|
|
|
|
#endif /* __LSTACK_RTC_API_H_ */
|
|
diff --git a/src/lstack/include/lstack_rtw_api.h b/src/lstack/include/lstack_rtw_api.h
|
|
index facf4c0..d0f77b7 100644
|
|
--- a/src/lstack/include/lstack_rtw_api.h
|
|
+++ b/src/lstack/include/lstack_rtw_api.h
|
|
@@ -14,6 +14,7 @@
|
|
#define _LSTACK_RTW_API_H_
|
|
|
|
#include <sys/epoll.h>
|
|
+#include <sys/select.h>
|
|
#include <sys/socket.h>
|
|
|
|
int rtw_socket(int domain, int type, int protocol);
|
|
@@ -44,4 +45,6 @@ int rtw_close(int s);
|
|
int rtw_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
|
|
int rtw_epoll_create1(int flags);
|
|
int rtw_epoll_create(int flags);
|
|
+int rtw_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
|
|
+
|
|
#endif /* _LSTACK_RTW_API_H_ */
|
|
diff --git a/src/lstack/include/posix/lstack_epoll.h b/src/lstack/include/posix/lstack_epoll.h
|
|
index c42f3a5..9c34eb3 100644
|
|
--- a/src/lstack/include/posix/lstack_epoll.h
|
|
+++ b/src/lstack/include/posix/lstack_epoll.h
|
|
@@ -78,6 +78,7 @@ int32_t lstack_rtc_epoll_ctl(int32_t epfd, int32_t op, int32_t fd, struct epoll_
|
|
int32_t lstack_rtw_epoll_wait(int32_t epfd, struct epoll_event *events, int32_t maxevents, int32_t timeout);
|
|
int32_t lstack_rtc_epoll_wait(int32_t epfd, struct epoll_event* events, int32_t maxevents, int32_t timeout);
|
|
int32_t lstack_poll(struct pollfd *fds, nfds_t nfds, int32_t timeout);
|
|
+int lstack_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeval);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
--
|
|
2.27.0
|
|
|