summaryrefslogtreecommitdiff
path: root/pjlib/src/pjlib-test
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-03-22 11:49:19 +0000
committerBenny Prijono <bennylp@teluu.com>2006-03-22 11:49:19 +0000
commitd494bf04e608a604eaa96bd65b9daa72a1d98252 (patch)
tree7c44cbf3f7f6858673ad5c7601ece5005ad835c2 /pjlib/src/pjlib-test
parentac843019cc56478c4423e0181e2ec1452d84e75b (diff)
Fixed bug in ioqueue with IO Completion Port backend, where events may still be called after key is unregistered
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@349 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib/src/pjlib-test')
-rw-r--r--pjlib/src/pjlib-test/ioq_udp.c174
-rw-r--r--pjlib/src/pjlib-test/main_win32.c2
2 files changed, 175 insertions, 1 deletions
diff --git a/pjlib/src/pjlib-test/ioq_udp.c b/pjlib/src/pjlib-test/ioq_udp.c
index 5f933afa..b81764f2 100644
--- a/pjlib/src/pjlib-test/ioq_udp.c
+++ b/pjlib/src/pjlib-test/ioq_udp.c
@@ -313,6 +313,173 @@ on_error:
}
+
+static void on_read_complete(pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ pj_ssize_t bytes_read)
+{
+ unsigned *p_packet_cnt = pj_ioqueue_get_user_data(key);
+
+ PJ_UNUSED_ARG(op_key);
+ PJ_UNUSED_ARG(bytes_read);
+
+ (*p_packet_cnt)++;
+}
+
+/*
+ * unregister_test()
+ * Check if callback is still called after socket has been unregistered or
+ * closed.
+ */
+static int unregister_test(void)
+{
+ enum { RPORT = 50000, SPORT = 50001 };
+ pj_pool_t *pool;
+ pj_ioqueue_t *ioqueue;
+ pj_sock_t ssock;
+ pj_sock_t rsock;
+ int addrlen;
+ pj_sockaddr_in addr;
+ pj_ioqueue_key_t *key;
+ pj_ioqueue_op_key_t opkey;
+ pj_ioqueue_callback cb;
+ unsigned packet_cnt;
+ char sendbuf[10], recvbuf[10];
+ pj_ssize_t bytes;
+ pj_time_val timeout;
+ pj_status_t status;
+
+ pool = pj_pool_create(mem, "test", 4000, 4000, NULL);
+ if (!pool) {
+ app_perror("Unable to create pool", PJ_ENOMEM);
+ return -100;
+ }
+
+ status = pj_ioqueue_create(pool, 16, &ioqueue);
+ if (status != PJ_SUCCESS) {
+ app_perror("Error creating ioqueue", status);
+ return -110;
+ }
+
+ /* Create sender socket */
+ status = app_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, SPORT, &ssock);
+ if (status != PJ_SUCCESS) {
+ app_perror("Error initializing socket", status);
+ return -120;
+ }
+
+ /* Create receiver socket. */
+ status = app_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, RPORT, &rsock);
+ if (status != PJ_SUCCESS) {
+ app_perror("Error initializing socket", status);
+ return -130;
+ }
+
+ /* Register rsock to ioqueue. */
+ pj_memset(&cb, 0, sizeof(cb));
+ cb.on_read_complete = &on_read_complete;
+ packet_cnt = 0;
+ status = pj_ioqueue_register_sock(pool, ioqueue, rsock, &packet_cnt,
+ &cb, &key);
+ if (status != PJ_SUCCESS) {
+ app_perror("Error registering to ioqueue", status);
+ return -140;
+ }
+
+ /* Init operation key. */
+ pj_ioqueue_op_key_init(&opkey, sizeof(opkey));
+
+ /* Start reading. */
+ bytes = sizeof(recvbuf);
+ status = pj_ioqueue_recv( key, &opkey, recvbuf, &bytes, 0);
+ if (status != PJ_EPENDING) {
+ app_perror("Expecting PJ_EPENDING, but got this", status);
+ return -150;
+ }
+
+ /* Init destination address. */
+ addrlen = sizeof(addr);
+ status = pj_sock_getsockname(rsock, &addr, &addrlen);
+ if (status != PJ_SUCCESS) {
+ app_perror("getsockname error", status);
+ return -160;
+ }
+
+ /* Override address with 127.0.0.1, since getsockname will return
+ * zero in the address field.
+ */
+ addr.sin_addr = pj_inet_addr2("127.0.0.1");
+
+ /* Init buffer to send */
+ pj_ansi_strcpy(sendbuf, "Hello0123");
+
+ /* Send one packet. */
+ bytes = sizeof(sendbuf);
+ status = pj_sock_sendto(ssock, sendbuf, &bytes, 0,
+ &addr, sizeof(addr));
+
+ if (status != PJ_SUCCESS) {
+ app_perror("sendto error", status);
+ return -170;
+ }
+
+ /* Check if packet is received. */
+ timeout.sec = 1; timeout.msec = 0;
+ pj_ioqueue_poll(ioqueue, &timeout);
+
+ if (packet_cnt != 1) {
+ return -180;
+ }
+
+ /* Just to make sure things are settled.. */
+ pj_thread_sleep(100);
+
+ /* Start reading again. */
+ bytes = sizeof(recvbuf);
+ status = pj_ioqueue_recv( key, &opkey, recvbuf, &bytes, 0);
+ if (status != PJ_EPENDING) {
+ app_perror("Expecting PJ_EPENDING, but got this", status);
+ return -190;
+ }
+
+ /* Reset packet counter */
+ packet_cnt = 0;
+
+ /* Send one packet. */
+ bytes = sizeof(sendbuf);
+ status = pj_sock_sendto(ssock, sendbuf, &bytes, 0,
+ &addr, sizeof(addr));
+
+ if (status != PJ_SUCCESS) {
+ app_perror("sendto error", status);
+ return -200;
+ }
+
+ /* Now unregister and close socket. */
+ pj_ioqueue_unregister(key);
+ pj_sock_close(rsock);
+
+ /* Poll ioqueue. */
+ timeout.sec = 1; timeout.msec = 0;
+ pj_ioqueue_poll(ioqueue, &timeout);
+
+ /* Must NOT receive any packets after socket is closed! */
+ if (packet_cnt > 0) {
+ PJ_LOG(3,(THIS_FILE, "....errror: not expecting to receive packet "
+ "after socket has been closed"));
+ return -210;
+ }
+
+ /* Success */
+ pj_sock_close(ssock);
+ pj_ioqueue_destroy(ioqueue);
+
+ pj_pool_release(pool);
+
+ return 0;
+}
+
+
/*
* Testing with many handles.
* This will just test registering PJ_IOQUEUE_MAX_HANDLES count
@@ -625,6 +792,13 @@ int udp_ioqueue_test()
}
PJ_LOG(3, (THIS_FILE, "....compliance test ok"));
+
+ PJ_LOG(3, (THIS_FILE, "...unregister test (%s)", pj_ioqueue_name()));
+ if ((status=unregister_test()) != 0) {
+ return status;
+ }
+ PJ_LOG(3, (THIS_FILE, "....unregister test ok"));
+
if ((status=many_handles_test()) != 0) {
return status;
}
diff --git a/pjlib/src/pjlib-test/main_win32.c b/pjlib/src/pjlib-test/main_win32.c
index 07d91870..6024a953 100644
--- a/pjlib/src/pjlib-test/main_win32.c
+++ b/pjlib/src/pjlib-test/main_win32.c
@@ -55,7 +55,7 @@ static void write_log(int level, const char *data, int len)
PJ_UNUSED_ARG(level);
PJ_UNUSED_ARG(len);
SendMessage(hwndLog, EM_REPLACESEL, FALSE,
- (LPARAM)PJ_STRING_TO_NATIVE(data,wdata));
+ (LPARAM)PJ_STRING_TO_NATIVE(data,wdata,256));
}