Added test for multiple selects (disabled by default)

This commit is contained in:
goldsimon 2010-03-07 18:45:27 +00:00
parent 5604a40915
commit 8cd0218330
1 changed files with 180 additions and 4 deletions

View File

@ -204,9 +204,9 @@ sockex_nonblocking_connect(void *arg)
ret = lwip_select(s + 1, &readset, &writeset, &errset, NULL);
ticks_b = sys_now();
LWIP_ASSERT("ret > 0", ret > 0);
LWIP_ASSERT("!FD_ISSET(s, &writeset)", !FD_ISSET(s, &writeset));
LWIP_ASSERT("!FD_ISSET(s, &readset)", !FD_ISSET(s, &readset));
LWIP_ASSERT("FD_ISSET(s, &errset)", FD_ISSET(s, &errset));
LWIP_ASSERT("!FD_ISSET(s, &readset)", !FD_ISSET(s, &readset));
LWIP_ASSERT("!FD_ISSET(s, &writeset)", !FD_ISSET(s, &writeset));
/* close */
ret = lwip_close(s);
@ -228,6 +228,9 @@ sockex_testrecv(void *arg)
struct sockaddr_in addr;
size_t len;
char rxbuf[1024];
fd_set readset;
fd_set errset;
struct timeval tv;
LWIP_UNUSED_ARG(arg);
/* set up address to connect to */
@ -248,7 +251,7 @@ sockex_testrecv(void *arg)
/* should succeed */
LWIP_ASSERT("ret == 0", ret == 0);
/* set recv timeout */
/* set recv timeout (100 ms) */
opt = 100;
ret = lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &opt, sizeof(int));
LWIP_ASSERT("ret == 0", ret == 0);
@ -271,13 +274,25 @@ sockex_testrecv(void *arg)
ret = lwip_write(s, SNDSTR2, len);
LWIP_ASSERT("ret == len", ret == (int)len);
/* wait a while */
/* wait a while: should be enough for the server to send a response */
sys_msleep(1000);
/* should not time out but receive a response */
ret = lwip_read(s, rxbuf, 1024);
LWIP_ASSERT("ret > 0", ret > 0);
/* now select should directly return because the socket is readable */
FD_ZERO(&readset);
FD_ZERO(&errset);
FD_SET(s, &readset);
FD_SET(s, &errset);
tv.tv_sec = 10;
tv.tv_usec = 0;
ret = lwip_select(s + 1, &readset, NULL, &errset, &tv);
LWIP_ASSERT("ret == 1", ret == 1);
LWIP_ASSERT("!FD_ISSET(s, &errset)", !FD_ISSET(s, &errset));
LWIP_ASSERT("FD_ISSET(s, &readset)", FD_ISSET(s, &readset));
/* should not time out but receive a response */
ret = lwip_read(s, rxbuf, 1024);
/* might receive a second packet for HTTP/1.1 servers */
@ -294,10 +309,171 @@ sockex_testrecv(void *arg)
printf("sockex_testrecv finished successfully\n");
}
/** helper struct for the 2 functions below (multithreaded: thread-argument) */
struct sockex_select_helper {
int socket;
int wait_read;
int expect_read;
int wait_write;
int expect_write;
int wait_err;
int expect_err;
int wait_ms;
sys_sem_t sem;
};
/** helper thread to wait for socket events using select */
static void
sockex_select_waiter(void *arg)
{
struct sockex_select_helper *helper = (struct sockex_select_helper *)arg;
int ret;
fd_set readset;
fd_set writeset;
fd_set errset;
struct timeval tv;
LWIP_ASSERT("helper != NULL", helper != NULL);
FD_ZERO(&readset);
FD_ZERO(&writeset);
FD_ZERO(&errset);
if (helper->wait_read) {
FD_SET(helper->socket, &readset);
}
if (helper->wait_write) {
FD_SET(helper->socket, &writeset);
}
if (helper->wait_err) {
FD_SET(helper->socket, &errset);
}
tv.tv_sec = helper->wait_ms / 1000;
tv.tv_usec = (helper->wait_ms % 1000) * 1000;
ret = lwip_select(helper->socket, &readset, &writeset, &errset, &tv);
if (helper->expect_read || helper->expect_write || helper->expect_err) {
LWIP_ASSERT("ret > 0", ret > 0);
} else {
LWIP_ASSERT("ret == 0", ret == 0);
}
if (helper->expect_read) {
LWIP_ASSERT("FD_ISSET(helper->socket, &readset)", FD_ISSET(helper->socket, &readset));
} else {
LWIP_ASSERT("!FD_ISSET(helper->socket, &readset)", !FD_ISSET(helper->socket, &readset));
}
if (helper->expect_write) {
LWIP_ASSERT("FD_ISSET(helper->socket, &writeset)", FD_ISSET(helper->socket, &writeset));
} else {
LWIP_ASSERT("!FD_ISSET(helper->socket, &writeset)", !FD_ISSET(helper->socket, &writeset));
}
if (helper->expect_err) {
LWIP_ASSERT("FD_ISSET(helper->socket, &errset)", FD_ISSET(helper->socket, &errset));
} else {
LWIP_ASSERT("!FD_ISSET(helper->socket, &errset)", !FD_ISSET(helper->socket, &errset));
}
sys_sem_signal(&helper->sem);
}
/** This is an example function that tests
more than one thread being active in select. */
static void
sockex_testtwoselects(void *arg)
{
int s1;
int s2;
int ret;
struct sockaddr_in addr;
size_t len;
err_t lwiperr;
struct sockex_select_helper h1, h2, h3, h4;
LWIP_UNUSED_ARG(arg);
/* set up address to connect to */
memset(&addr, 0, sizeof(addr));
addr.sin_len = sizeof(addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(SOCK_TARGET_PORT);
addr.sin_addr.s_addr = inet_addr(SOCK_TARGET_HOST);
/* create the sockets */
s1 = lwip_socket(AF_INET, SOCK_STREAM, 0);
LWIP_ASSERT("s1 >= 0", s1 >= 0);
s2 = lwip_socket(AF_INET, SOCK_STREAM, 0);
LWIP_ASSERT("s2 >= 0", s2 >= 0);
/* connect, should succeed */
ret = lwip_connect(s1, (struct sockaddr*)&addr, sizeof(addr));
LWIP_ASSERT("ret == 0", ret == 0);
ret = lwip_connect(s2, (struct sockaddr*)&addr, sizeof(addr));
LWIP_ASSERT("ret == 0", ret == 0);
/* write the start of a GET request */
#define SNDSTR1 "G"
len = strlen(SNDSTR1);
ret = lwip_write(s1, SNDSTR1, len);
LWIP_ASSERT("ret == len", ret == (int)len);
ret = lwip_write(s2, SNDSTR1, len);
LWIP_ASSERT("ret == len", ret == (int)len);
h1.wait_read = 1;
h1.wait_write = 1;
h1.wait_err = 1;
h1.expect_read = 0;
h1.expect_write = 0;
h1.expect_err = 0;
lwiperr = sys_sem_new(&h1.sem, 0);
LWIP_ASSERT("lwiperr == ERR_OK", lwiperr == ERR_OK);
h1.socket = s1;
h1.wait_ms = 500;
h2 = h1;
lwiperr = sys_sem_new(&h2.sem, 0);
LWIP_ASSERT("lwiperr == ERR_OK", lwiperr == ERR_OK);
h2.socket = s2;
h2.wait_ms = 1000;
h3 = h1;
lwiperr = sys_sem_new(&h3.sem, 0);
LWIP_ASSERT("lwiperr == ERR_OK", lwiperr == ERR_OK);
h3.socket = s2;
h3.wait_ms = 1500;
h4 = h1;
lwiperr = sys_sem_new(&h4.sem, 0);
LWIP_ASSERT("lwiperr == ERR_OK", lwiperr == ERR_OK);
h4.socket = s2;
h4.wait_ms = 2000;
/* select: all sockets should time out if the other side is a good HTTP server */
sys_thread_new("sockex_select_waiter1", sockex_select_waiter, &h2, 0, 0);
sys_msleep(100);
sys_thread_new("sockex_select_waiter2", sockex_select_waiter, &h1, 0, 0);
sys_msleep(100);
sys_thread_new("sockex_select_waiter2", sockex_select_waiter, &h4, 0, 0);
sys_msleep(100);
sys_thread_new("sockex_select_waiter2", sockex_select_waiter, &h3, 0, 0);
sys_sem_wait(&h1.sem);
sys_sem_wait(&h2.sem);
sys_sem_wait(&h3.sem);
sys_sem_wait(&h4.sem);
/* close */
ret = lwip_close(s1);
LWIP_ASSERT("ret == 0", ret == 0);
ret = lwip_close(s2);
LWIP_ASSERT("ret == 0", ret == 0);
printf("sockex_testtwoselects finished successfully\n");
}
void socket_examples_init(void)
{
sys_thread_new("sockex_nonblocking_connect", sockex_nonblocking_connect, NULL, 0, 0);
sys_thread_new("sockex_testrecv", sockex_testrecv, NULL, 0, 0);
/*sys_thread_new("sockex_testtwoselects", sockex_testtwoselects, NULL, 0, 0);*/
}
#endif /* LWIP_SOCKETS */