From 35ba3a877db77bdd82701e17002400105cf3d70c Mon Sep 17 00:00:00 2001 From: goldsimon Date: Tue, 13 Jun 2017 21:07:34 +0200 Subject: [PATCH] Moved NUM_SOCKETS and struct lwip_sock to sockets_priv.h; added test case for fd_use count with select --- src/api/sockets.c | 47 +++-------------------- src/include/lwip/priv/sockets_priv.h | 44 +++++++++++++++++++++ test/unit/api/test_sockets.c | 57 ++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 41 deletions(-) diff --git a/src/api/sockets.c b/src/api/sockets.c index 1a5a69f8..4677f593 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c @@ -192,47 +192,6 @@ static void sockaddr_to_ipaddr_port(const struct sockaddr* sockaddr, ip_addr_t* #define LWIP_SO_SNDRCVTIMEO_GET_MS(optval) ((((const struct timeval *)(optval))->tv_sec * 1000U) + (((const struct timeval *)(optval))->tv_usec / 1000U)) #endif -#define NUM_SOCKETS MEMP_NUM_NETCONN - -/** This is overridable for the rare case where more than 255 threads - * select on the same socket... - */ -#ifndef SELWAIT_T -#define SELWAIT_T u8_t -#endif - -union lwip_sock_lastdata { - struct netbuf *netbuf; - struct pbuf *pbuf; -}; - -/** Contains all internal pointers and states used for a socket */ -struct lwip_sock { - /** sockets currently are built on netconns, each socket has one netconn */ - struct netconn *conn; - /** data that was left from the previous read */ - union lwip_sock_lastdata lastdata; -#if LWIP_SOCKET_SELECT - /** number of times data was received, set by event_callback(), - tested by the receive and select functions */ - s16_t rcvevent; - /** number of times data was ACKed (free send buffer), set by event_callback(), - tested by select */ - u16_t sendevent; - /** error happened for this socket, set by event_callback(), tested by select */ - u16_t errevent; - /** counter of how many threads are waiting for this socket using select */ - SELWAIT_T select_waiting; -#endif /* LWIP_SOCKET_SELECT */ -#if LWIP_NETCONN_FULLDUPLEX - /* counter of how many threads are using a struct lwip_sock (not the 'int') */ - u8_t fd_used; - /* status of pending close/delete actions */ - u8_t fd_free_pending; -#define LWIP_SOCK_FD_FREE_TCP 1 -#define LWIP_SOCK_FD_FREE_FREE 2 -#endif -}; #if LWIP_NETCONN_SEM_PER_THREAD #define SELECT_SEM_T sys_sem_t* @@ -424,6 +383,12 @@ tryget_socket_unconn_nouse(int fd) return &sockets[s]; } +struct lwip_sock* +lwip_socket_dbg_get_socket(int fd) +{ + return tryget_socket_unconn_nouse(fd); +} + /* Translate a socket 'int' into a pointer (only fails if the index is invalid) */ static struct lwip_sock * tryget_socket_unconn(int fd) diff --git a/src/include/lwip/priv/sockets_priv.h b/src/include/lwip/priv/sockets_priv.h index aad7e693..6a3a6980 100644 --- a/src/include/lwip/priv/sockets_priv.h +++ b/src/include/lwip/priv/sockets_priv.h @@ -48,6 +48,48 @@ extern "C" { #endif +#define NUM_SOCKETS MEMP_NUM_NETCONN + +/** This is overridable for the rare case where more than 255 threads + * select on the same socket... + */ +#ifndef SELWAIT_T +#define SELWAIT_T u8_t +#endif + +union lwip_sock_lastdata { + struct netbuf *netbuf; + struct pbuf *pbuf; +}; + +/** Contains all internal pointers and states used for a socket */ +struct lwip_sock { + /** sockets currently are built on netconns, each socket has one netconn */ + struct netconn *conn; + /** data that was left from the previous read */ + union lwip_sock_lastdata lastdata; +#if LWIP_SOCKET_SELECT + /** number of times data was received, set by event_callback(), + tested by the receive and select functions */ + s16_t rcvevent; + /** number of times data was ACKed (free send buffer), set by event_callback(), + tested by select */ + u16_t sendevent; + /** error happened for this socket, set by event_callback(), tested by select */ + u16_t errevent; + /** counter of how many threads are waiting for this socket using select */ + SELWAIT_T select_waiting; +#endif /* LWIP_SOCKET_SELECT */ +#if LWIP_NETCONN_FULLDUPLEX + /* counter of how many threads are using a struct lwip_sock (not the 'int') */ + u8_t fd_used; + /* status of pending close/delete actions */ + u8_t fd_free_pending; +#define LWIP_SOCK_FD_FREE_TCP 1 +#define LWIP_SOCK_FD_FREE_FREE 2 +#endif +}; + #if LWIP_SOCKET_SET_ERRNO #ifndef set_errno #define set_errno(err) do { if (err) { errno = (err); } } while(0) @@ -92,6 +134,8 @@ struct lwip_setgetsockopt_data { } #endif +struct lwip_sock* lwip_socket_dbg_get_socket(int fd); + #endif /* LWIP_SOCKET */ #endif /* LWIP_HDR_SOCKETS_PRIV_H */ diff --git a/test/unit/api/test_sockets.c b/test/unit/api/test_sockets.c index 643b54a7..a4362142 100644 --- a/test/unit/api/test_sockets.c +++ b/test/unit/api/test_sockets.c @@ -3,11 +3,30 @@ #include "lwip/mem.h" #include "lwip/opt.h" #include "lwip/sockets.h" +#include "lwip/priv/sockets_priv.h" #include "lwip/stats.h" #include "lwip/tcpip.h" +static int +test_sockets_get_used_count(void) +{ + int used = 0; + int i; + + for (i = 0; i < NUM_SOCKETS; i++) { + struct lwip_sock* s = lwip_socket_dbg_get_socket(i); + if (s != NULL) { + if (s->fd_used) { + used++; + } + } + } + return used; +} + + /* Setups/teardown functions */ static void @@ -18,6 +37,7 @@ sockets_setup(void) static void sockets_teardown(void) { + fail_unless(test_sockets_get_used_count() == 0); } #ifndef NUM_SOCKETS @@ -573,6 +593,42 @@ START_TEST(test_sockets_msgapis) } END_TEST +START_TEST(test_sockets_select) +{ +#if LWIP_SOCKET_SELECT + int s; + int ret; + fd_set readset; + fd_set writeset; + fd_set errset; + struct timeval tv; + + fail_unless(test_sockets_get_used_count() == 0); + + s = lwip_socket(AF_INET, SOCK_STREAM, 0); + fail_unless(s >= 0); + fail_unless(test_sockets_get_used_count() == 0); + + FD_ZERO(&readset); + FD_SET(s, &readset); + FD_ZERO(&writeset); + FD_SET(s, &writeset); + FD_ZERO(&errset); + FD_SET(s, &errset); + + tv.tv_sec = tv.tv_usec = 0; + ret = lwip_select(s + 1, &readset, &writeset, &errset, &tv); + fail_unless(ret == 0); + fail_unless(test_sockets_get_used_count() == 0); + + ret = lwip_close(s); + fail_unless(ret == 0); + +#endif + LWIP_UNUSED_ARG(_i); +} +END_TEST + /** Create the suite including all tests for this module */ Suite * sockets_suite(void) @@ -581,6 +637,7 @@ sockets_suite(void) TESTFUNC(test_sockets_basics), TESTFUNC(test_sockets_allfunctions_basic), TESTFUNC(test_sockets_msgapis), + TESTFUNC(test_sockets_select), }; return create_suite("SOCKETS", tests, sizeof(tests)/sizeof(testfunc), sockets_setup, sockets_teardown); }