Skip to content

Commit 6d79715

Browse files
committed
test: Add tests for timeout on select with PROXY_TO_PTHREAD
Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
1 parent 9f40870 commit 6d79715

File tree

2 files changed

+169
-0
lines changed

2 files changed

+169
-0
lines changed

test/core/test_select_blocking.c

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
#include <sys/select.h>
2+
#include <time.h>
3+
#include <assert.h>
4+
#include <stdio.h>
5+
#include <unistd.h>
6+
#include <pthread.h>
7+
#include <string.h>
8+
#include <sys/time.h>
9+
10+
// Check if timeout works without fds
11+
void test_timeout_without_fds() {
12+
struct timeval tv, begin, end;
13+
14+
tv.tv_sec = 1;
15+
tv.tv_usec = 0;
16+
gettimeofday(&begin, NULL);
17+
assert(select(0, NULL, NULL, NULL, &tv) == 0);
18+
gettimeofday(&end, NULL);
19+
assert((end.tv_sec - begin.tv_sec) * 1000000 + end.tv_usec - begin.tv_usec >= 1000000);
20+
}
21+
22+
// Check if timeout works with fds without events
23+
void test_timeout_with_fds_without_events() {
24+
struct timeval tv, begin, end;
25+
fd_set readfds;
26+
int pipe_a[2];
27+
28+
assert(pipe(pipe_a) == 0);
29+
30+
tv.tv_sec = 1;
31+
tv.tv_usec = 0;
32+
FD_ZERO(&readfds);
33+
FD_SET(pipe_a[0], &readfds);
34+
gettimeofday(&begin, NULL);
35+
assert(select(pipe_a[0] + 1, &readfds, NULL, NULL, &tv) == 0);
36+
gettimeofday(&end, NULL);
37+
assert((end.tv_sec - begin.tv_sec) * 1000000 + end.tv_usec - begin.tv_usec >= 1000000);
38+
39+
close(pipe_a[0]); close(pipe_a[1]);
40+
}
41+
42+
int pipe_shared[2];
43+
44+
void *write_after_2s(void * arg) {
45+
const char *t = "test\n";
46+
47+
sleep(2);
48+
write(pipe_shared[1], t, strlen(t));
49+
50+
return NULL;
51+
}
52+
53+
// Check if select can unblock on an event
54+
void test_unblock_select() {
55+
struct timeval begin, end;
56+
fd_set readfds;
57+
int maxfd;
58+
pthread_t tid;
59+
int pipe_a[2];
60+
61+
assert(pipe(pipe_a) == 0);
62+
assert(pipe(pipe_shared) == 0);
63+
64+
FD_ZERO(&readfds);
65+
FD_SET(pipe_a[0], &readfds);
66+
FD_SET(pipe_shared[0], &readfds);
67+
maxfd = (pipe_a[0] > pipe_shared[0] ? pipe_a[0] : pipe_shared[0]);
68+
assert(pthread_create(&tid, NULL, write_after_2s, NULL) == 0);
69+
gettimeofday(&begin, NULL);
70+
assert(select(maxfd + 1, &readfds, NULL, NULL, NULL) == 1);
71+
gettimeofday(&end, NULL);
72+
assert(FD_ISSET(pipe_shared[0], &readfds));
73+
assert((end.tv_sec - begin.tv_sec) * 1000000 + end.tv_usec - begin.tv_usec >= 1000000);
74+
75+
pthread_join(tid, NULL);
76+
77+
close(pipe_a[0]); close(pipe_a[1]);
78+
close(pipe_shared[0]); close(pipe_shared[1]);
79+
}
80+
81+
void *do_select_in_thread(void * arg) {
82+
struct timeval begin, end;
83+
fd_set readfds;
84+
int maxfd;
85+
struct timeval tv;
86+
int duration;
87+
tv.tv_sec = 4;
88+
tv.tv_usec = 0;
89+
90+
FD_ZERO(&readfds);
91+
FD_SET(pipe_shared[0], &readfds);
92+
maxfd = pipe_shared[0];
93+
94+
gettimeofday(&begin, NULL);
95+
assert(select(maxfd + 1, &readfds, NULL, NULL, &tv) == 1);
96+
gettimeofday(&end, NULL);
97+
assert(FD_ISSET(pipe_shared[0], &readfds));
98+
duration = (end.tv_sec - begin.tv_sec) * 1000000 + end.tv_usec - begin.tv_usec;
99+
assert((duration >= 1000000) && (duration < 4000000));
100+
101+
return NULL;
102+
}
103+
104+
// Check if select works in threads
105+
void test_select_in_threads() {
106+
pthread_t tid1, tid2;
107+
const char *t = "test\n";
108+
109+
assert(pipe(pipe_shared) == 0);
110+
111+
assert(pthread_create(&tid1, NULL, do_select_in_thread, NULL) == 0);
112+
assert(pthread_create(&tid2, NULL, do_select_in_thread, NULL) == 0);
113+
114+
sleep(2);
115+
write(pipe_shared[1], t, strlen(t));
116+
117+
pthread_join(tid1, NULL);
118+
pthread_join(tid2, NULL);
119+
120+
close(pipe_shared[0]); close(pipe_shared[1]);
121+
}
122+
123+
// Check if select works with ready fds
124+
void test_ready_fds() {
125+
struct timeval tv;
126+
fd_set readfds;
127+
int maxfd;
128+
const char *t = "test\n";
129+
int pipe_c[2];
130+
int pipe_d[2];
131+
132+
assert(pipe(pipe_c) == 0);
133+
assert(pipe(pipe_d) == 0);
134+
135+
write(pipe_c[1], t, strlen(t));
136+
write(pipe_d[1], t, strlen(t));
137+
maxfd = (pipe_c[0] > pipe_d[0] ? pipe_c[0] : pipe_d[0]);
138+
139+
tv.tv_sec = 0;
140+
tv.tv_usec = 0;
141+
FD_ZERO(&readfds);
142+
FD_SET(pipe_c[0], &readfds);
143+
FD_SET(pipe_d[0], &readfds);
144+
assert(select(maxfd + 1, &readfds, NULL, NULL, &tv) == 2);
145+
assert(FD_ISSET(pipe_c[0], &readfds));
146+
assert(FD_ISSET(pipe_d[0], &readfds));
147+
148+
FD_ZERO(&readfds);
149+
FD_SET(pipe_c[0], &readfds);
150+
FD_SET(pipe_d[0], &readfds);
151+
assert(select(maxfd + 1, &readfds, NULL, NULL, NULL) == 2);
152+
assert(FD_ISSET(pipe_c[0], &readfds));
153+
assert(FD_ISSET(pipe_d[0], &readfds));
154+
155+
close(pipe_c[0]); close(pipe_c[1]);
156+
close(pipe_d[0]); close(pipe_d[1]);
157+
}
158+
159+
int main() {
160+
test_select_in_threads();
161+
test_timeout_without_fds();
162+
test_timeout_with_fds_without_events();
163+
test_unblock_select();
164+
test_ready_fds();
165+
return 0;
166+
}

test/test_core.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9665,6 +9665,9 @@ def test_wasm_global(self, dynlink):
96659665
def test_syscall_intercept(self):
96669666
self.do_core_test('test_syscall_intercept.c')
96679667

9668+
def test_select_blocking(self):
9669+
self.do_runf('core/test_select_blocking.c', cflags=['-pthread', '-sPROXY_TO_PTHREAD=1', '-sEXIT_RUNTIME=1'])
9670+
96689671
@also_without_bigint
96699672
def test_jslib_i64_params(self):
96709673
# Tests the defineI64Param and receiveI64ParamAsI53 helpers that are

0 commit comments

Comments
 (0)