-
Notifications
You must be signed in to change notification settings - Fork 802
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add iocp crash mock test (to reproduce the issue #985)
- Loading branch information
Showing
4 changed files
with
164 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
/** | ||
* ioqueue iocp crash reproduce test (issue #985) | ||
*/ | ||
#include <pjlib.h> | ||
#include "test.h" | ||
|
||
#define THIS_FILE "ioq_iocp_crash_test.c" | ||
|
||
struct sock_info_t { | ||
pj_activesock_t *asock; | ||
pj_sockaddr bound_addr; | ||
pj_pool_t *pool; | ||
}; | ||
|
||
struct iocp_test_t { | ||
pj_pool_t *pool; | ||
pj_ioqueue_t *ioq; | ||
pj_thread_t *tid; | ||
pj_bool_t quit; | ||
struct sock_info_t *socks[8]; | ||
pj_activesock_t *asock_send; | ||
}; | ||
|
||
|
||
static int worker_thread(void *p) | ||
{ | ||
struct iocp_test_t *test = (struct iocp_test_t *)p; | ||
|
||
while(!test->quit) { | ||
pj_time_val timeout = {0, 10}; | ||
pj_ioqueue_poll(test->ioq, &timeout); | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
static pj_bool_t on_data_recvfrom(pj_activesock_t *asock, | ||
void *data, | ||
pj_size_t size, | ||
const pj_sockaddr_t *src_addr, | ||
int addr_len, | ||
pj_status_t status) | ||
{ | ||
(void)asock; | ||
(void)src_addr; | ||
(void)addr_len; | ||
PJ_LOG(3, (THIS_FILE, "on_data_recvfrom() data:%.*s, status:%d", (int)size, (char *)data, status)); | ||
return PJ_TRUE; | ||
} | ||
|
||
int ioqueue_iocp_crash_test(void) | ||
{ | ||
struct iocp_test_t *test; | ||
pj_pool_t *pool; | ||
pj_status_t status; | ||
unsigned i; | ||
pj_activesock_cfg cfg; | ||
pj_activesock_cb cb; | ||
struct sock_info_t *sock_info; | ||
pj_sockaddr loc_addr; | ||
pj_str_t loop = {"127.0.0.1", 9}; | ||
|
||
if (strcmp(pj_ioqueue_name(), "iocp")) { | ||
/* ignore if ioqueue framework is not iocp */ | ||
return PJ_SUCCESS; | ||
} | ||
|
||
pool = pj_pool_create(mem, "iocp-crash-test", 1000, 1000, NULL); | ||
test = PJ_POOL_ZALLOC_T(pool, struct iocp_test_t); | ||
test->pool = pool; | ||
status = pj_ioqueue_create(pool, PJ_IOQUEUE_MAX_HANDLES, &test->ioq); | ||
if (status != PJ_SUCCESS) { | ||
status = -900; | ||
goto on_error; | ||
} | ||
|
||
status = pj_thread_create(pool, "iocp-crash-test", worker_thread, test, 0, 0, &test->tid); | ||
if (status != PJ_SUCCESS) { | ||
status = -901; | ||
goto on_error; | ||
} | ||
|
||
pj_activesock_cfg_default(&cfg); | ||
pj_bzero(&cb, sizeof(cb)); | ||
cb.on_data_recvfrom = on_data_recvfrom; | ||
|
||
/* create send socket */ | ||
status = pj_activesock_create_udp(pool, NULL, &cfg, test->ioq, &cb, NULL, &test->asock_send, NULL); | ||
if (status != PJ_SUCCESS) { | ||
status = -902; | ||
goto on_error; | ||
} | ||
|
||
/* create sockets to recevie */ | ||
pj_sockaddr_init(pj_AF_INET(), &loc_addr, &loop, 0); | ||
for (i = 0; i < PJ_ARRAY_SIZE(test->socks); i++) { | ||
pool = pj_pool_create(mem, "sock%p", 1000, 1000, NULL); | ||
sock_info = PJ_POOL_ZALLOC_T(pool, struct sock_info_t); | ||
sock_info->pool = pool; | ||
|
||
status = pj_activesock_create_udp(pool, &loc_addr, &cfg, test->ioq, &cb, NULL, &sock_info->asock, &sock_info->bound_addr); | ||
if (status != PJ_SUCCESS) { | ||
status = -903; | ||
pj_pool_release(pool); | ||
goto on_error; | ||
} | ||
test->socks[i] = sock_info; | ||
pj_activesock_start_recvfrom(sock_info->asock, pool, 2000, 0); | ||
} | ||
|
||
for (i = 0; i < PJ_ARRAY_SIZE(test->socks); i++) { | ||
pj_ioqueue_op_key_t *send_key; | ||
pj_str_t data; | ||
pj_ssize_t sent; | ||
pj_pool_t *pool = test->pool; | ||
|
||
sock_info = test->socks[i]; | ||
send_key = PJ_POOL_ZALLOC_T(pool, pj_ioqueue_op_key_t); | ||
pj_strdup2_with_null(pool, &data, "hello"); | ||
sent = data.slen; | ||
status = pj_activesock_sendto(test->asock_send, send_key, data.ptr, &sent, 0, | ||
&sock_info->bound_addr, | ||
pj_sockaddr_get_len(&sock_info->bound_addr)); | ||
if (status != PJ_SUCCESS && status != PJ_EPENDING) { | ||
char buf[80]; | ||
pj_sockaddr_print(&sock_info->bound_addr, buf, sizeof(buf), 3); | ||
PJ_PERROR(2, (THIS_FILE, status, "send error, dest:%s", buf)); | ||
} | ||
} | ||
|
||
pj_thread_sleep(20); | ||
for (i = 0; i < PJ_ARRAY_SIZE(test->socks); i++) { | ||
sock_info = test->socks[i]; | ||
pj_activesock_close(sock_info->asock); | ||
pj_pool_release(sock_info->pool); | ||
test->socks[i] = NULL; | ||
} | ||
|
||
pj_thread_sleep(20); | ||
test->quit = PJ_TRUE; | ||
status = PJ_SUCCESS; | ||
|
||
on_error: | ||
if (test->tid) | ||
pj_thread_join(test->tid); | ||
for (i = 0; i < PJ_ARRAY_SIZE(test->socks); i++) { | ||
sock_info = test->socks[i]; | ||
if (!sock_info) | ||
break; | ||
pj_activesock_close(sock_info->asock); | ||
pj_pool_release(sock_info->pool); | ||
} | ||
if (test->ioq) | ||
pj_ioqueue_destroy(test->ioq); | ||
pj_pool_release(test->pool); | ||
return status; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters