diff --git a/mongoose.c b/mongoose.c index ff996417..1798365b 100644 --- a/mongoose.c +++ b/mongoose.c @@ -3926,6 +3926,7 @@ struct mg_connection *mg_sntp_connect(struct mg_mgr *mgr, const char *url, + #if MG_ENABLE_SOCKET #if MG_ARCH == MG_ARCH_WIN32 && MG_ENABLE_WINSOCK #define MG_SOCK_ERRNO WSAGetLastError() @@ -4393,6 +4394,38 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) { FreeRTOS_FD_CLR(c->fd, mgr->ss, eSELECT_READ | eSELECT_EXCEPT | eSELECT_WRITE); } +#elif MG_ENABLE_POLL + size_t i = 0, n = 0; + for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) n++; + struct pollfd fds[n == 0 ? 1 : n]; // Avoid zero-length VLA + + memset(fds, 0, sizeof(fds)); + for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next, i++) { + if (c->is_closing || c->is_resolving || FD(c) == INVALID_SOCKET) { + // No valid socket yet, ignore + } else { + fds[i].fd = FD(c); + fds[i].events |= POLLIN; + if (c->is_connecting || (c->send.len > 0 && c->is_tls_hs == 0)) { + fds[i].events |= POLLOUT; + } + } + } + + if (poll(fds, n, ms) < 0) { + MG_ERROR(("poll failed, errno: %d", MG_SOCK_ERRNO)); + } else { + i = 0; + for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next, i++) { + if (c->is_closing || c->is_resolving || FD(c) == INVALID_SOCKET) { + // No valid socket yet, ignore + } else { + c->is_readable = (unsigned) (fds[i].revents & POLLIN ? true : false); + c->is_writable = (unsigned) (fds[i].revents & POLLOUT ? true : false); + fds[i].revents = 0; + } + } + } #else struct timeval tv = {ms / 1000, (ms % 1000) * 1000}, tv_zero = {0, 0}; struct mg_connection *c; diff --git a/mongoose.h b/mongoose.h index dbb992e5..e0178675 100644 --- a/mongoose.h +++ b/mongoose.h @@ -436,7 +436,11 @@ extern int SockSet(SOCKET hSock, int Type, int Prop, void *pbuf, int size); #include #include #include +#if MG_ENABLE_POLL +#include +#else #include +#endif #include #include #include @@ -578,6 +582,10 @@ int sscanf(const char *, const char *, ...); #define MG_ENABLE_MIP 0 #endif +#ifndef MG_ENABLE_POLL +#define MG_ENABLE_POLL 0 +#endif + #ifndef MG_ENABLE_FATFS #define MG_ENABLE_FATFS 0 #endif diff --git a/src/arch_unix.h b/src/arch_unix.h index dd696e22..548c1e54 100644 --- a/src/arch_unix.h +++ b/src/arch_unix.h @@ -22,7 +22,11 @@ #include #include #include +#if MG_ENABLE_POLL +#include +#else #include +#endif #include #include #include diff --git a/src/config.h b/src/config.h index 0d68c468..6dda7931 100644 --- a/src/config.h +++ b/src/config.h @@ -4,6 +4,10 @@ #define MG_ENABLE_MIP 0 #endif +#ifndef MG_ENABLE_POLL +#define MG_ENABLE_POLL 0 +#endif + #ifndef MG_ENABLE_FATFS #define MG_ENABLE_FATFS 0 #endif diff --git a/src/sock.c b/src/sock.c index 700067be..87ea3aee 100644 --- a/src/sock.c +++ b/src/sock.c @@ -1,3 +1,4 @@ +#include "arch.h" #include "dns.h" #include "event.h" #include "log.h" @@ -475,6 +476,38 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) { FreeRTOS_FD_CLR(c->fd, mgr->ss, eSELECT_READ | eSELECT_EXCEPT | eSELECT_WRITE); } +#elif MG_ENABLE_POLL + size_t i = 0, n = 0; + for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) n++; + struct pollfd fds[n == 0 ? 1 : n]; // Avoid zero-length VLA + + memset(fds, 0, sizeof(fds)); + for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next, i++) { + if (c->is_closing || c->is_resolving || FD(c) == INVALID_SOCKET) { + // No valid socket yet, ignore + } else { + fds[i].fd = FD(c); + fds[i].events |= POLLIN; + if (c->is_connecting || (c->send.len > 0 && c->is_tls_hs == 0)) { + fds[i].events |= POLLOUT; + } + } + } + + if (poll(fds, n, ms) < 0) { + MG_ERROR(("poll failed, errno: %d", MG_SOCK_ERRNO)); + } else { + i = 0; + for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next, i++) { + if (c->is_closing || c->is_resolving || FD(c) == INVALID_SOCKET) { + // No valid socket yet, ignore + } else { + c->is_readable = (unsigned) (fds[i].revents & POLLIN ? true : false); + c->is_writable = (unsigned) (fds[i].revents & POLLOUT ? true : false); + fds[i].revents = 0; + } + } + } #else struct timeval tv = {ms / 1000, (ms % 1000) * 1000}, tv_zero = {0, 0}; struct mg_connection *c;