diff --git a/src/api/sockets.c b/src/api/sockets.c index 8a7fdcaf..8b7370d4 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c @@ -262,7 +262,7 @@ static void lwip_socket_drop_registered_mld6_memberships(int s); /** The global array of available sockets */ static struct lwip_sock sockets[NUM_SOCKETS]; -#if LWIP_SOCKET_SELECT +#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL #if LWIP_TCPIP_CORE_LOCKING /* protect the select_cb_list using core lock */ #define LWIP_SOCKET_SELECT_DECL_PROTECT(lev) @@ -279,7 +279,7 @@ static volatile int select_cb_ctr; #endif /* LWIP_TCPIP_CORE_LOCKING */ /** The global list of tasks waiting for select */ static struct lwip_select_cb *select_cb_list; -#endif /* LWIP_SOCKET_SELECT */ +#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */ #define sock_set_errno(sk, e) do { \ const int sockerr = (e); \ @@ -287,7 +287,7 @@ static struct lwip_select_cb *select_cb_list; } while (0) /* Forward declaration of some functions */ -#if LWIP_SOCKET_SELECT +#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len); #define DEFAULT_SOCKET_EVENTCB event_callback static void select_check_waiters(int s, int has_recvevent, int has_sendevent, int has_errevent, struct lwip_sock *sock); @@ -1692,7 +1692,7 @@ lwip_writev(int s, const struct iovec *iov, int iovcnt) return lwip_sendmsg(s, &msg, 0); } -#if LWIP_SOCKET_SELECT +#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL /* Add select_cb to select_cb_list. */ static void lwip_link_select_cb(struct lwip_select_cb *select_cb) @@ -1741,8 +1741,9 @@ lwip_unlink_select_cb(struct lwip_select_cb *select_cb) #endif LWIP_SOCKET_SELECT_UNPROTECT(lev); } +#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */ - +#if LWIP_SOCKET_SELECT /** * Go through the readset and writeset lists and see which socket of the sockets * set in the sets has events. On return, readset, writeset and exceptset have @@ -1941,18 +1942,12 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, to use local variables (unless we're running in MPU compatible mode). */ API_SELECT_CB_VAR_DECLARE(select_cb); - API_SELECT_CB_VAR_ALLOC(select_cb, set_errno(ENOMEM); return -1); + API_SELECT_CB_VAR_ALLOC(select_cb, set_errno(ENOMEM); lwip_select_dec_sockets_used(maxfdp1, &used_sockets); return -1); + memset(&API_SELECT_CB_VAR_REF(select_cb), 0, sizeof(struct lwip_select_cb)); - API_SELECT_CB_VAR_REF(select_cb).next = NULL; - API_SELECT_CB_VAR_REF(select_cb).prev = NULL; API_SELECT_CB_VAR_REF(select_cb).readset = readset; API_SELECT_CB_VAR_REF(select_cb).writeset = writeset; API_SELECT_CB_VAR_REF(select_cb).exceptset = exceptset; -#if LWIP_SOCKET_POLL - API_SELECT_CB_VAR_REF(select_cb).poll_fds = NULL; - API_SELECT_CB_VAR_REF(select_cb).poll_nfds = 0; -#endif - API_SELECT_CB_VAR_REF(select_cb).sem_signalled = 0; #if LWIP_NETCONN_SEM_PER_THREAD API_SELECT_CB_VAR_REF(select_cb).sem = LWIP_NETCONN_THREAD_SEM_GET(); #else /* LWIP_NETCONN_SEM_PER_THREAD */ @@ -2095,9 +2090,9 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, } return nready; } +#endif /* LWIP_SOCKET_SELECT */ #if LWIP_SOCKET_POLL - /** Options for the lwip_pollscan function. */ enum lwip_pollscan_opts { @@ -2260,7 +2255,6 @@ lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout) u32_t waitres = 0; int nready; u32_t msectimeout; - struct lwip_select_cb select_cb; #if LWIP_NETCONN_SEM_PER_THREAD int waited = 0; #endif @@ -2281,36 +2275,35 @@ lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout) /* If we don't have any current events, then suspend if we are supposed to */ if (!nready) { + API_SELECT_CB_VAR_DECLARE(select_cb); + if (timeout == 0) { LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll: no timeout, returning 0\n")); goto return_success; } + API_SELECT_CB_VAR_ALLOC(select_cb, set_errno(EAGAIN); lwip_poll_dec_sockets_used(fds, nfds); return -1); + memset(&API_SELECT_CB_VAR_REF(select_cb), 0, sizeof(struct lwip_select_cb)); /* None ready: add our semaphore to list: We don't actually need any dynamic memory. Our entry on the list is only valid while we are in this function, so it's ok to use local variables. */ - select_cb.next = NULL; - select_cb.prev = NULL; - select_cb.readset = NULL; - select_cb.writeset = NULL; - select_cb.exceptset = NULL; - select_cb.poll_fds = fds; - select_cb.poll_nfds = nfds; - select_cb.sem_signalled = 0; + API_SELECT_CB_VAR_REF(select_cb).poll_fds = fds; + API_SELECT_CB_VAR_REF(select_cb).poll_nfds = nfds; #if LWIP_NETCONN_SEM_PER_THREAD - select_cb.sem = LWIP_NETCONN_THREAD_SEM_GET(); + API_SELECT_CB_VAR_REF(select_cb).sem = LWIP_NETCONN_THREAD_SEM_GET(); #else /* LWIP_NETCONN_SEM_PER_THREAD */ - if (sys_sem_new(&select_cb.sem, 0) != ERR_OK) { + if (sys_sem_new(&API_SELECT_CB_VAR_REF(select_cb).sem, 0) != ERR_OK) { /* failed to create semaphore */ - set_errno(ENOMEM); + set_errno(EAGAIN); lwip_poll_dec_sockets_used(fds, nfds); + API_SELECT_CB_VAR_FREE(select_cb); return -1; } #endif /* LWIP_NETCONN_SEM_PER_THREAD */ - lwip_link_select_cb(&select_cb); + lwip_link_select_cb(&API_SELECT_CB_VAR_REF(select_cb)); /* Increase select_waiting for each socket we are interested in. Also, check for events again: there could have been events between @@ -2327,7 +2320,7 @@ lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout) LWIP_ASSERT("timeout > 0", timeout > 0); msectimeout = timeout; } - waitres = sys_arch_sem_wait(SELECT_SEM_PTR(select_cb.sem), msectimeout); + waitres = sys_arch_sem_wait(SELECT_SEM_PTR(API_SELECT_CB_VAR_REF(select_cb).sem), msectimeout); #if LWIP_NETCONN_SEM_PER_THREAD waited = 1; #endif @@ -2337,16 +2330,17 @@ lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout) and check which events occurred while we waited. */ nready = lwip_pollscan(fds, nfds, LWIP_POLLSCAN_DEC_WAIT); - lwip_unlink_select_cb(&select_cb); + lwip_unlink_select_cb(&API_SELECT_CB_VAR_REF(select_cb)); #if LWIP_NETCONN_SEM_PER_THREAD if (select_cb.sem_signalled && (!waited || (waitres == SYS_ARCH_TIMEOUT))) { /* don't leave the thread-local semaphore signalled */ - sys_arch_sem_wait(select_cb.sem, 1); + sys_arch_sem_wait(API_SELECT_CB_VAR_REF(select_cb).sem, 1); } #else /* LWIP_NETCONN_SEM_PER_THREAD */ - sys_sem_free(&select_cb.sem); + sys_sem_free(&API_SELECT_CB_VAR_REF(select_cb).sem); #endif /* LWIP_NETCONN_SEM_PER_THREAD */ + API_SELECT_CB_VAR_FREE(select_cb); if (nready < 0) { /* This happens when a socket got closed while waiting */ @@ -2396,9 +2390,9 @@ lwip_poll_should_wake(const struct lwip_select_cb *scb, int fd, struct lwip_sock } return 0; } - #endif /* LWIP_SOCKET_POLL */ +#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL /** * Callback registered in the netconn layer for each socket-netconn. * Processes recvevent (data available) and wakes up tasks waiting for select. @@ -2528,9 +2522,16 @@ again: int do_signal = 0; #if LWIP_SOCKET_POLL if (scb->poll_fds != NULL) { + LWIP_UNUSED_ARG(has_recvevent); + LWIP_UNUSED_ARG(has_sendevent); + LWIP_UNUSED_ARG(has_errevent); do_signal = lwip_poll_should_wake(scb, s, sock); - } else + } #endif /* LWIP_SOCKET_POLL */ +#if LWIP_SOCKET_SELECT && LWIP_SOCKET_POLL + else +#endif /* LWIP_SOCKET_SELECT && LWIP_SOCKET_POLL */ +#if LWIP_SOCKET_SELECT { LWIP_UNUSED_ARG(sock); /* Test this select call for our socket */ @@ -2550,6 +2551,7 @@ again: } } } +#endif /* LWIP_SOCKET_SELECT */ if (do_signal) { scb->sem_signalled = 1; /* For !LWIP_TCPIP_CORE_LOCKING, we don't call SYS_ARCH_UNPROTECT() before signaling @@ -2575,7 +2577,7 @@ again: SYS_ARCH_UNPROTECT(lev); #endif } -#endif /* LWIP_SOCKET_SELECT */ +#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */ /** * Close one end of a full-duplex connection. diff --git a/src/include/lwip/priv/memp_std.h b/src/include/lwip/priv/memp_std.h index 4ad0b6d4..c694194a 100644 --- a/src/include/lwip/priv/memp_std.h +++ b/src/include/lwip/priv/memp_std.h @@ -78,9 +78,9 @@ LWIP_MEMPOOL(DNS_API_MSG, MEMP_NUM_DNS_API_MSG, sizeof(struct dns_api_msg #if LWIP_SOCKET && !LWIP_TCPIP_CORE_LOCKING LWIP_MEMPOOL(SOCKET_SETGETSOCKOPT_DATA, MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA, sizeof(struct lwip_setgetsockopt_data), "SOCKET_SETGETSOCKOPT_DATA") #endif -#if LWIP_SOCKET && LWIP_SOCKET_SELECT +#if LWIP_SOCKET && (LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL) LWIP_MEMPOOL(SELECT_CB, MEMP_NUM_SELECT_CB, sizeof(struct lwip_select_cb), "SELECT_CB") -#endif /* LWIP_SOCKET && LWIP_SOCKET_SELECT */ +#endif /* LWIP_SOCKET && (LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL) */ #if LWIP_NETIF_API LWIP_MEMPOOL(NETIFAPI_MSG, MEMP_NUM_NETIFAPI_MSG, sizeof(struct netifapi_msg), "NETIFAPI_MSG") #endif diff --git a/src/include/lwip/priv/sockets_priv.h b/src/include/lwip/priv/sockets_priv.h index 22075e15..d8f9904d 100644 --- a/src/include/lwip/priv/sockets_priv.h +++ b/src/include/lwip/priv/sockets_priv.h @@ -69,7 +69,7 @@ struct lwip_sock { struct netconn *conn; /** data that was left from the previous read */ union lwip_sock_lastdata lastdata; -#if LWIP_SOCKET_SELECT +#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL /** number of times data was received, set by event_callback(), tested by the receive and select functions */ s16_t rcvevent; @@ -80,7 +80,7 @@ struct lwip_sock { u16_t errevent; /** counter of how many threads are waiting for this socket using select */ SELWAIT_T select_waiting; -#endif /* LWIP_SOCKET_SELECT */ +#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */ #if LWIP_NETCONN_FULLDUPLEX /* counter of how many threads are using a struct lwip_sock (not the 'int') */ u8_t fd_used; @@ -133,7 +133,7 @@ struct lwip_setgetsockopt_data { struct lwip_sock* lwip_socket_dbg_get_socket(int fd); -#if LWIP_SOCKET_SELECT +#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL #if LWIP_NETCONN_SEM_PER_THREAD #define SELECT_SEM_T sys_sem_t* @@ -149,24 +149,26 @@ struct lwip_select_cb { struct lwip_select_cb *next; /** Pointer to the previous waiting task */ struct lwip_select_cb *prev; +#if LWIP_SOCKET_SELECT /** readset passed to select */ fd_set *readset; /** writeset passed to select */ fd_set *writeset; /** unimplemented: exceptset passed to select */ fd_set *exceptset; +#endif /* LWIP_SOCKET_SELECT */ #if LWIP_SOCKET_POLL /** fds passed to poll; NULL if select */ struct pollfd *poll_fds; /** nfds passed to poll; 0 if select */ nfds_t poll_nfds; -#endif +#endif /* LWIP_SOCKET_POLL */ /** don't signal the same semaphore twice: set to 1 when signalled */ int sem_signalled; /** semaphore to wake up a task waiting for select */ SELECT_SEM_T sem; }; -#endif /* LWIP_SOCKET_SELECT */ +#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */ #endif /* LWIP_SOCKET */