blob: 1e3b6dc81a164006e529ac5d5d532a320f61a6b8 [file] [log] [blame]
Benny Prijonoe0312a72005-11-18 00:16:43 +00001/* $Id$ */
Benny Prijonoe7224612005-11-13 19:40:44 +00002/*
Benny Prijonoe0312a72005-11-18 00:16:43 +00003 * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
Benny Prijonoe7224612005-11-13 19:40:44 +00004 *
Benny Prijonoe0312a72005-11-18 00:16:43 +00005 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
Benny Prijonoe7224612005-11-13 19:40:44 +00009 *
Benny Prijonoe0312a72005-11-18 00:16:43 +000010 * This program is distributed in the hope that it will be useful,
Benny Prijonoe7224612005-11-13 19:40:44 +000011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Benny Prijonoe0312a72005-11-18 00:16:43 +000012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Benny Prijonoe7224612005-11-13 19:40:44 +000018 */
19#include "test.h"
20
21
22/**
23 * \page page_pjlib_ioqueue_udp_test Test: I/O Queue (UDP)
24 *
25 * This file provides implementation to test the
26 * functionality of the I/O queue when UDP socket is used.
27 *
28 *
29 * This file is <b>pjlib-test/ioq_udp.c</b>
30 *
31 * \include pjlib-test/ioq_udp.c
32 */
33
34
35#if INCLUDE_UDP_IOQUEUE_TEST
36
37#include <pjlib.h>
38
39#include <pj/compat/socket.h>
40
41#define THIS_FILE "test_udp"
42#define PORT 51233
43#define LOOP 100
44#define BUF_MIN_SIZE 32
45#define BUF_MAX_SIZE 2048
46#define SOCK_INACTIVE_MIN (1)
47#define SOCK_INACTIVE_MAX (PJ_IOQUEUE_MAX_HANDLES - 2)
48#define POOL_SIZE (2*BUF_MAX_SIZE + SOCK_INACTIVE_MAX*128 + 2048)
49
50#undef TRACE_
51#define TRACE_(msg) PJ_LOG(3,(THIS_FILE,"....." msg))
52
53static pj_ssize_t callback_read_size,
54 callback_write_size,
55 callback_accept_status,
56 callback_connect_status;
57static pj_ioqueue_key_t *callback_read_key,
58 *callback_write_key,
59 *callback_accept_key,
60 *callback_connect_key;
61static pj_ioqueue_op_key_t *callback_read_op,
62 *callback_write_op,
63 *callback_accept_op;
64
65static void on_ioqueue_read(pj_ioqueue_key_t *key,
66 pj_ioqueue_op_key_t *op_key,
67 pj_ssize_t bytes_read)
68{
69 callback_read_key = key;
70 callback_read_op = op_key;
71 callback_read_size = bytes_read;
72}
73
74static void on_ioqueue_write(pj_ioqueue_key_t *key,
75 pj_ioqueue_op_key_t *op_key,
76 pj_ssize_t bytes_written)
77{
78 callback_write_key = key;
79 callback_write_op = op_key;
80 callback_write_size = bytes_written;
81}
82
83static void on_ioqueue_accept(pj_ioqueue_key_t *key,
84 pj_ioqueue_op_key_t *op_key,
85 pj_sock_t sock, int status)
86{
87 PJ_UNUSED_ARG(sock);
88 callback_accept_key = key;
89 callback_accept_op = op_key;
90 callback_accept_status = status;
91}
92
93static void on_ioqueue_connect(pj_ioqueue_key_t *key, int status)
94{
95 callback_connect_key = key;
96 callback_connect_status = status;
97}
98
99static pj_ioqueue_callback test_cb =
100{
101 &on_ioqueue_read,
102 &on_ioqueue_write,
103 &on_ioqueue_accept,
104 &on_ioqueue_connect,
105};
106
107#ifdef PJ_WIN32
108# define S_ADDR S_un.S_addr
109#else
110# define S_ADDR s_addr
111#endif
112
113/*
114 * compliance_test()
115 * To test that the basic IOQueue functionality works. It will just exchange
116 * data between two sockets.
117 */
118static int compliance_test(void)
119{
120 pj_sock_t ssock=-1, csock=-1;
121 pj_sockaddr_in addr;
122 int addrlen;
123 pj_pool_t *pool = NULL;
124 char *send_buf, *recv_buf;
125 pj_ioqueue_t *ioque = NULL;
126 pj_ioqueue_key_t *skey, *ckey;
127 pj_ioqueue_op_key_t read_op, write_op;
128 int bufsize = BUF_MIN_SIZE;
129 pj_ssize_t bytes, status = -1;
130 pj_str_t temp;
131 pj_bool_t send_pending, recv_pending;
132 pj_status_t rc;
133
134 pj_set_os_error(PJ_SUCCESS);
135
136 // Create pool.
137 pool = pj_pool_create(mem, NULL, POOL_SIZE, 4000, NULL);
138
139 // Allocate buffers for send and receive.
140 send_buf = (char*)pj_pool_alloc(pool, bufsize);
141 recv_buf = (char*)pj_pool_alloc(pool, bufsize);
142
143 // Allocate sockets for sending and receiving.
144 TRACE_("creating sockets...");
145 rc = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, &ssock);
146 if (rc==PJ_SUCCESS)
147 rc = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, &csock);
148 else
149 csock = PJ_INVALID_SOCKET;
150 if (rc != PJ_SUCCESS) {
151 app_perror("...ERROR in pj_sock_socket()", rc);
152 status=-1; goto on_error;
153 }
154
155 // Bind server socket.
156 TRACE_("bind socket...");
157 memset(&addr, 0, sizeof(addr));
158 addr.sin_family = PJ_AF_INET;
159 addr.sin_port = pj_htons(PORT);
160 if (pj_sock_bind(ssock, &addr, sizeof(addr))) {
161 status=-10; goto on_error;
162 }
163
164 // Create I/O Queue.
165 TRACE_("create ioqueue...");
166 rc = pj_ioqueue_create(pool, PJ_IOQUEUE_MAX_HANDLES, &ioque);
167 if (rc != PJ_SUCCESS) {
168 status=-20; goto on_error;
169 }
170
171 // Register server and client socket.
172 // We put this after inactivity socket, hopefully this can represent the
173 // worst waiting time.
174 TRACE_("registering first sockets...");
175 rc = pj_ioqueue_register_sock(pool, ioque, ssock, NULL,
176 &test_cb, &skey);
177 if (rc != PJ_SUCCESS) {
178 app_perror("...error(10): ioqueue_register error", rc);
179 status=-25; goto on_error;
180 }
181 TRACE_("registering second sockets...");
182 rc = pj_ioqueue_register_sock( pool, ioque, csock, NULL,
183 &test_cb, &ckey);
184 if (rc != PJ_SUCCESS) {
185 app_perror("...error(11): ioqueue_register error", rc);
186 status=-26; goto on_error;
187 }
188
189 // Set destination address to send the packet.
190 TRACE_("set destination address...");
191 temp = pj_str("127.0.0.1");
192 if ((rc=pj_sockaddr_in_init(&addr, &temp, PORT)) != 0) {
193 app_perror("...error: unable to resolve 127.0.0.1", rc);
194 status=-26; goto on_error;
195 }
196
197 // Randomize send_buf.
198 pj_create_random_string(send_buf, bufsize);
199
200 // Register reading from ioqueue.
201 TRACE_("start recvfrom...");
202 addrlen = sizeof(addr);
203 bytes = bufsize;
204 rc = pj_ioqueue_recvfrom(skey, &read_op, recv_buf, &bytes, 0,
205 &addr, &addrlen);
206 if (rc != PJ_SUCCESS && rc != PJ_EPENDING) {
207 app_perror("...error: pj_ioqueue_recvfrom", rc);
208 status=-28; goto on_error;
209 } else if (rc == PJ_EPENDING) {
210 recv_pending = 1;
211 PJ_LOG(3, (THIS_FILE,
212 "......ok: recvfrom returned pending"));
213 } else {
214 PJ_LOG(3, (THIS_FILE,
215 "......error: recvfrom returned immediate ok!"));
216 status=-29; goto on_error;
217 }
218
219 // Write must return the number of bytes.
220 TRACE_("start sendto...");
221 bytes = bufsize;
222 rc = pj_ioqueue_sendto(ckey, &write_op, send_buf, &bytes, 0, &addr,
223 sizeof(addr));
224 if (rc != PJ_SUCCESS && rc != PJ_EPENDING) {
225 app_perror("...error: pj_ioqueue_sendto", rc);
226 status=-30; goto on_error;
227 } else if (rc == PJ_EPENDING) {
228 send_pending = 1;
229 PJ_LOG(3, (THIS_FILE,
230 "......ok: sendto returned pending"));
231 } else {
232 send_pending = 0;
233 PJ_LOG(3, (THIS_FILE,
234 "......ok: sendto returned immediate success"));
235 }
236
237 // reset callback variables.
238 callback_read_size = callback_write_size = 0;
239 callback_accept_status = callback_connect_status = -2;
240 callback_read_key = callback_write_key =
241 callback_accept_key = callback_connect_key = NULL;
242 callback_read_op = callback_write_op = NULL;
243
244 // Poll if pending.
245 while (send_pending || recv_pending) {
246 int rc;
247 pj_time_val timeout = { 5, 0 };
248
249 TRACE_("poll...");
250 rc = pj_ioqueue_poll(ioque, &timeout);
251
252 if (rc == 0) {
253 PJ_LOG(1,(THIS_FILE, "...ERROR: timed out..."));
254 status=-45; goto on_error;
255 } else if (rc < 0) {
256 app_perror("...ERROR in ioqueue_poll()", rc);
257 status=-50; goto on_error;
258 }
259
260 if (callback_read_key != NULL) {
261 if (callback_read_size != bufsize) {
262 status=-61; goto on_error;
263 }
264 if (callback_read_key != skey) {
265 status=-65; goto on_error;
266 }
267 if (callback_read_op != &read_op) {
268 status=-66; goto on_error;
269 }
270
271 if (memcmp(send_buf, recv_buf, bufsize) != 0) {
272 status=-70; goto on_error;
273 }
274
275
276 recv_pending = 0;
277 }
278
279 if (callback_write_key != NULL) {
280 if (callback_write_size != bufsize) {
281 status=-73; goto on_error;
282 }
283 if (callback_write_key != ckey) {
284 status=-75; goto on_error;
285 }
286 if (callback_write_op != &write_op) {
287 status=-76; goto on_error;
288 }
289
290 send_pending = 0;
291 }
292 }
293
294 // Success
295 status = 0;
296
297on_error:
298 if (status != 0) {
299 char errbuf[128];
300 PJ_LOG(1, (THIS_FILE,
301 "...compliance test error: status=%d, os_err=%d (%s)",
302 status, pj_get_netos_error(),
303 pj_strerror(pj_get_netos_error(), errbuf, sizeof(errbuf))));
304 }
305 if (ssock)
306 pj_sock_close(ssock);
307 if (csock)
308 pj_sock_close(csock);
309 if (ioque != NULL)
310 pj_ioqueue_destroy(ioque);
311 pj_pool_release(pool);
312 return status;
313
314}
315
316/*
317 * Testing with many handles.
318 * This will just test registering PJ_IOQUEUE_MAX_HANDLES count
319 * of sockets to the ioqueue.
320 */
321static int many_handles_test(void)
322{
323 enum { MAX = PJ_IOQUEUE_MAX_HANDLES };
324 pj_pool_t *pool;
325 pj_ioqueue_t *ioqueue;
326 pj_sock_t *sock;
327 pj_ioqueue_key_t **key;
328 pj_status_t rc;
329 int count, i;
330
331 PJ_LOG(3,(THIS_FILE,"...testing with so many handles"));
332
333 pool = pj_pool_create(mem, NULL, 4000, 4000, NULL);
334 if (!pool)
335 return PJ_ENOMEM;
336
337 key = pj_pool_alloc(pool, MAX*sizeof(pj_ioqueue_key_t*));
338 sock = pj_pool_alloc(pool, MAX*sizeof(pj_sock_t));
339
340 /* Create IOQueue */
341 rc = pj_ioqueue_create(pool, MAX, &ioqueue);
342 if (rc != PJ_SUCCESS || ioqueue == NULL) {
343 app_perror("...error in pj_ioqueue_create", rc);
344 return -10;
345 }
346
347 /* Register as many sockets. */
348 for (count=0; count<MAX; ++count) {
349 sock[count] = PJ_INVALID_SOCKET;
350 rc = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, &sock[count]);
351 if (rc != PJ_SUCCESS || sock[count] == PJ_INVALID_SOCKET) {
352 PJ_LOG(3,(THIS_FILE, "....unable to create %d-th socket, rc=%d",
353 count, rc));
354 break;
355 }
356 key[count] = NULL;
357 rc = pj_ioqueue_register_sock(pool, ioqueue, sock[count],
358 NULL, &test_cb, &key[count]);
359 if (rc != PJ_SUCCESS || key[count] == NULL) {
360 PJ_LOG(3,(THIS_FILE, "....unable to register %d-th socket, rc=%d",
361 count, rc));
362 return -30;
363 }
364 }
365
366 /* Test complete. */
367
368 /* Now deregister and close all handles. */
369
370 for (i=0; i<count; ++i) {
371 rc = pj_ioqueue_unregister(key[i]);
372 if (rc != PJ_SUCCESS) {
373 app_perror("...error in pj_ioqueue_unregister", rc);
374 }
375 rc = pj_sock_close(sock[i]);
376 if (rc != PJ_SUCCESS) {
377 app_perror("...error in pj_sock_close", rc);
378 }
379 }
380
381 rc = pj_ioqueue_destroy(ioqueue);
382 if (rc != PJ_SUCCESS) {
383 app_perror("...error in pj_ioqueue_destroy", rc);
384 }
385
386 pj_pool_release(pool);
387
388 PJ_LOG(3,(THIS_FILE,"....many_handles_test() ok"));
389
390 return 0;
391}
392
393/*
394 * Multi-operation test.
395 */
396
397/*
398 * Benchmarking IOQueue
399 */
400static int bench_test(int bufsize, int inactive_sock_count)
401{
402 pj_sock_t ssock=-1, csock=-1;
403 pj_sockaddr_in addr;
404 pj_pool_t *pool = NULL;
405 pj_sock_t *inactive_sock=NULL;
406 pj_ioqueue_op_key_t *inactive_read_op;
407 char *send_buf, *recv_buf;
408 pj_ioqueue_t *ioque = NULL;
409 pj_ioqueue_key_t *skey, *ckey, *key;
410 pj_timestamp t1, t2, t_elapsed;
411 int rc=0, i;
412 pj_str_t temp;
413 char errbuf[128];
414
415 // Create pool.
416 pool = pj_pool_create(mem, NULL, POOL_SIZE, 4000, NULL);
417
418 // Allocate buffers for send and receive.
419 send_buf = (char*)pj_pool_alloc(pool, bufsize);
420 recv_buf = (char*)pj_pool_alloc(pool, bufsize);
421
422 // Allocate sockets for sending and receiving.
423 rc = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, &ssock);
424 if (rc == PJ_SUCCESS) {
425 rc = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, &csock);
426 } else
427 csock = PJ_INVALID_SOCKET;
428 if (rc != PJ_SUCCESS) {
429 app_perror("...error: pj_sock_socket()", rc);
430 goto on_error;
431 }
432
433 // Bind server socket.
434 memset(&addr, 0, sizeof(addr));
435 addr.sin_family = PJ_AF_INET;
436 addr.sin_port = pj_htons(PORT);
437 if (pj_sock_bind(ssock, &addr, sizeof(addr)))
438 goto on_error;
439
440 pj_assert(inactive_sock_count+2 <= PJ_IOQUEUE_MAX_HANDLES);
441
442 // Create I/O Queue.
443 rc = pj_ioqueue_create(pool, PJ_IOQUEUE_MAX_HANDLES, &ioque);
444 if (rc != PJ_SUCCESS) {
445 app_perror("...error: pj_ioqueue_create()", rc);
446 goto on_error;
447 }
448
449 // Allocate inactive sockets, and bind them to some arbitrary address.
450 // Then register them to the I/O queue, and start a read operation.
451 inactive_sock = (pj_sock_t*)pj_pool_alloc(pool,
452 inactive_sock_count*sizeof(pj_sock_t));
453 inactive_read_op = (pj_ioqueue_op_key_t*)pj_pool_alloc(pool,
454 inactive_sock_count*sizeof(pj_ioqueue_op_key_t));
455 memset(&addr, 0, sizeof(addr));
456 addr.sin_family = PJ_AF_INET;
457 for (i=0; i<inactive_sock_count; ++i) {
458 pj_ssize_t bytes;
459
460 rc = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, &inactive_sock[i]);
461 if (rc != PJ_SUCCESS || inactive_sock[i] < 0) {
462 app_perror("...error: pj_sock_socket()", rc);
463 goto on_error;
464 }
465 if ((rc=pj_sock_bind(inactive_sock[i], &addr, sizeof(addr))) != 0) {
466 pj_sock_close(inactive_sock[i]);
467 inactive_sock[i] = PJ_INVALID_SOCKET;
468 app_perror("...error: pj_sock_bind()", rc);
469 goto on_error;
470 }
471 rc = pj_ioqueue_register_sock(pool, ioque, inactive_sock[i],
472 NULL, &test_cb, &key);
473 if (rc != PJ_SUCCESS) {
474 pj_sock_close(inactive_sock[i]);
475 inactive_sock[i] = PJ_INVALID_SOCKET;
476 app_perror("...error(1): pj_ioqueue_register_sock()", rc);
477 PJ_LOG(3,(THIS_FILE, "....i=%d", i));
478 goto on_error;
479 }
480 bytes = bufsize;
481 rc = pj_ioqueue_recv(key, &inactive_read_op[i], recv_buf, &bytes, 0);
482 if ( rc < 0 && rc != PJ_EPENDING) {
483 pj_sock_close(inactive_sock[i]);
484 inactive_sock[i] = PJ_INVALID_SOCKET;
485 app_perror("...error: pj_ioqueue_read()", rc);
486 goto on_error;
487 }
488 }
489
490 // Register server and client socket.
491 // We put this after inactivity socket, hopefully this can represent the
492 // worst waiting time.
493 rc = pj_ioqueue_register_sock(pool, ioque, ssock, NULL,
494 &test_cb, &skey);
495 if (rc != PJ_SUCCESS) {
496 app_perror("...error(2): pj_ioqueue_register_sock()", rc);
497 goto on_error;
498 }
499
500 rc = pj_ioqueue_register_sock(pool, ioque, csock, NULL,
501 &test_cb, &ckey);
502 if (rc != PJ_SUCCESS) {
503 app_perror("...error(3): pj_ioqueue_register_sock()", rc);
504 goto on_error;
505 }
506
507 // Set destination address to send the packet.
508 pj_sockaddr_in_init(&addr, pj_cstr(&temp, "127.0.0.1"), PORT);
509
510 // Test loop.
511 t_elapsed.u64 = 0;
512 for (i=0; i<LOOP; ++i) {
513 pj_ssize_t bytes;
514 pj_ioqueue_op_key_t read_op, write_op;
515
516 // Randomize send buffer.
517 pj_create_random_string(send_buf, bufsize);
518
519 // Start reading on the server side.
520 bytes = bufsize;
521 rc = pj_ioqueue_recv(skey, &read_op, recv_buf, &bytes, 0);
522 if (rc < 0 && rc != PJ_EPENDING) {
523 app_perror("...error: pj_ioqueue_read()", rc);
524 break;
525 }
526
527 // Starts send on the client side.
528 bytes = bufsize;
529 rc = pj_ioqueue_sendto(ckey, &write_op, send_buf, &bytes, 0,
530 &addr, sizeof(addr));
531 if (rc != PJ_SUCCESS && rc != PJ_EPENDING) {
532 app_perror("...error: pj_ioqueue_write()", bytes);
533 rc = -1;
534 break;
535 }
536
537 // Begin time.
538 pj_get_timestamp(&t1);
539
540 // Poll the queue until we've got completion event in the server side.
541 callback_read_key = NULL;
542 callback_read_size = 0;
543 do {
544 rc = pj_ioqueue_poll(ioque, NULL);
545 } while (rc >= 0 && callback_read_key != skey);
546
547 // End time.
548 pj_get_timestamp(&t2);
549 t_elapsed.u64 += (t2.u64 - t1.u64);
550
551 if (rc < 0)
552 break;
553
554 // Compare recv buffer with send buffer.
555 if (callback_read_size != bufsize ||
556 memcmp(send_buf, recv_buf, bufsize))
557 {
558 rc = -1;
559 break;
560 }
561
562 // Poll until all events are exhausted, before we start the next loop.
563 do {
564 pj_time_val timeout = { 0, 10 };
565 rc = pj_ioqueue_poll(ioque, &timeout);
566 } while (rc>0);
567
568 rc = 0;
569 }
570
571 // Print results
572 if (rc == 0) {
573 pj_timestamp tzero;
574 pj_uint32_t usec_delay;
575
576 tzero.u32.hi = tzero.u32.lo = 0;
577 usec_delay = pj_elapsed_usec( &tzero, &t_elapsed);
578
579 PJ_LOG(3, (THIS_FILE, "...%10d %15d % 9d",
580 bufsize, inactive_sock_count, usec_delay));
581
582 } else {
583 PJ_LOG(2, (THIS_FILE, "...ERROR (buf:%d, fds:%d)",
584 bufsize, inactive_sock_count+2));
585 }
586
587 // Cleaning up.
588 for (i=0; i<inactive_sock_count; ++i)
589 pj_sock_close(inactive_sock[i]);
590 pj_sock_close(ssock);
591 pj_sock_close(csock);
592
593 pj_ioqueue_destroy(ioque);
594 pj_pool_release( pool);
595 return 0;
596
597on_error:
598 PJ_LOG(1,(THIS_FILE, "...ERROR: %s",
599 pj_strerror(pj_get_netos_error(), errbuf, sizeof(errbuf))));
600 if (ssock)
601 pj_sock_close(ssock);
602 if (csock)
603 pj_sock_close(csock);
604 for (i=0; i<inactive_sock_count && inactive_sock &&
605 inactive_sock[i]!=PJ_INVALID_SOCKET; ++i)
606 {
607 pj_sock_close(inactive_sock[i]);
608 }
609 if (ioque != NULL)
610 pj_ioqueue_destroy(ioque);
611 pj_pool_release( pool);
612 return -1;
613}
614
615int udp_ioqueue_test()
616{
617 int status;
618 int bufsize, sock_count;
619
620 PJ_LOG(3, (THIS_FILE, "...compliance test (%s)", pj_ioqueue_name()));
621 if ((status=compliance_test()) != 0) {
622 return status;
623 }
624 PJ_LOG(3, (THIS_FILE, "....compliance test ok"));
625
626 if ((status=many_handles_test()) != 0) {
627 return status;
628 }
629
630 PJ_LOG(4, (THIS_FILE, "...benchmarking different buffer size:"));
631 PJ_LOG(4, (THIS_FILE, "... note: buf=bytes sent, fds=# of fds, "
632 "elapsed=in timer ticks"));
633
634 PJ_LOG(3, (THIS_FILE, "...Benchmarking poll times for %s:", pj_ioqueue_name()));
635 PJ_LOG(3, (THIS_FILE, "...====================================="));
636 PJ_LOG(3, (THIS_FILE, "...Buf.size #inactive-socks Time/poll"));
637 PJ_LOG(3, (THIS_FILE, "... (bytes) (nanosec)"));
638 PJ_LOG(3, (THIS_FILE, "...====================================="));
639
640 for (bufsize=BUF_MIN_SIZE; bufsize <= BUF_MAX_SIZE; bufsize *= 2) {
641 if (bench_test(bufsize, SOCK_INACTIVE_MIN))
642 return -1;
643 }
644 bufsize = 512;
645 for (sock_count=SOCK_INACTIVE_MIN+2;
646 sock_count<=SOCK_INACTIVE_MAX+2;
647 sock_count *= 2)
648 {
649 //PJ_LOG(3,(THIS_FILE, "...testing with %d fds", sock_count));
650 if (bench_test(bufsize, sock_count-2))
651 return -1;
652 }
653 return 0;
654}
655
656#else
657/* To prevent warning about "translation unit is empty"
658 * when this test is disabled.
659 */
660int dummy_uiq_udp;
661#endif /* INCLUDE_UDP_IOQUEUE_TEST */
662
663