Index: pjproject/trunk/pjsip-apps/src/samples/pjsip-perf.c
===================================================================
--- pjproject/trunk/pjsip-apps/src/samples/pjsip-perf.c	(revision 580)
+++ pjproject/trunk/pjsip-apps/src/samples/pjsip-perf.c	(revision 581)
@@ -67,7 +67,17 @@
 #include <stdio.h>
 
-#define THIS_FILE	"pjsip-perf.c"
-#define DEFAULT_COUNT	(PJSIP_MAX_TSX_COUNT/2>10000?10000:PJSIP_MAX_TSX_COUNT/2)
-#define JOB_WINDOW	DEFAULT_COUNT
+#if defined(PJ_WIN32) && PJ_WIN32!=0
+#  include <windows.h>
+#endif
+
+#define THIS_FILE	    "pjsip-perf.c"
+#define DEFAULT_COUNT	    (PJSIP_MAX_TSX_COUNT/2>10000?10000:PJSIP_MAX_TSX_COUNT/2)
+#define JOB_WINDOW	    DEFAULT_COUNT
+#define TERMINATE_TSX(x,c)
+
+
+#ifndef CACHING_POOL_SIZE
+#   define CACHING_POOL_SIZE   (256*1024*1024)
+#endif
 
 
@@ -139,4 +149,5 @@
 			     job_finished,
 			     job_window;
+	unsigned	     stat_max_window;
 	pj_time_val	     first_request;
 	pj_time_val	     last_completion;
@@ -588,5 +599,6 @@
 
     /* Must create a pool factory before we can allocate any memory. */
-    pj_caching_pool_init(&app.cp, &pj_pool_factory_default_policy, 0);
+    pj_caching_pool_init(&app.cp, &pj_pool_factory_default_policy, 
+			 CACHING_POOL_SIZE);
 
     /* Create application pool for misc. */
@@ -633,5 +645,5 @@
 	    
 	    transport_type = "tcp";
-	    pj_sockaddr_in_init(&local_addr, 0, app.local_port);
+	    pj_sockaddr_in_init(&local_addr, 0, (pj_uint16_t)app.local_port);
 	    status = pjsip_tcp_transport_start(app.sip_endpt, &local_addr,
 					       app.thread_count, &tpfactory);
@@ -976,4 +988,5 @@
 	"   --stateless, -s         Set client to operate in stateless mode\n"
 	"                           (default: stateful)\n"
+	"   --window=COUNT, -w      Set maximum outstanding job in client (default: %d)\n"
 	"   --real-sdp              Generate real SDP from pjmedia, and also perform\n"
 	"                           proper SDP negotiation (default: dummy)\n"
@@ -986,5 +999,5 @@
 	"   - sip:1@server-addr     To handle requests statefully (INVITE and non-INVITE)\n"
 	"   - sip:2@server-addr     To handle INVITE call (INVITE only)\n",
-	DEFAULT_COUNT);
+	DEFAULT_COUNT, JOB_WINDOW);
 }
 
@@ -1011,4 +1024,5 @@
 	{ "verbose",        0, 0, 'v' },
 	{ "use-tcp",	    0, 0, 'T' },
+	{ "window",	    1, 0, 'w' },
 	{ NULL, 0, 0, 0 },
     };
@@ -1027,5 +1041,5 @@
     /* Parse options */
     pj_optind = 0;
-    while((c=pj_getopt_long(argc,argv, "p:c:m:t:hsv", 
+    while((c=pj_getopt_long(argc,argv, "p:c:m:t:w:hsv", 
 			    long_options, &option_index))!=-1) 
     {
@@ -1091,4 +1105,12 @@
 	    break;
 
+	case 'w':
+	    app.client.job_window = my_atoi(pj_optarg);
+	    if (app.client.job_window <= 0) {
+		PJ_LOG(3,(THIS_FILE, "Invalid --window %s", pj_optarg));
+		return -1;
+	    }
+	    break;
+
 	case 'T':
 	    app.use_tcp = PJ_TRUE;
@@ -1184,5 +1206,5 @@
 	tsx->mod_data[mod_test.id] = (void*)1;
 
-	pjsip_tsx_terminate(tsx, tsx->status_code);
+	TERMINATE_TSX(tsx, tsx->status_code);
     }
 }
@@ -1220,4 +1242,5 @@
 static int client_thread(void *arg)
 {
+    unsigned last_timeout_check = 0;
     pj_time_val end_time, now;
 
@@ -1240,13 +1263,21 @@
 	pj_status_t status;
 
+	/* Calculate current outstanding job */
+	outstanding = app.client.job_submitted - app.client.job_finished;
+
+	/* Update stats on max outstanding jobs */
+	if (outstanding > (int)app.client.stat_max_window)
+	    app.client.stat_max_window = outstanding;
+
 	/* Wait if there are more pending jobs than allowed in the
 	 * window.
 	 */
-	outstanding = app.client.job_submitted - app.client.job_finished;
-	while (outstanding >= (int)app.client.job_window) {
+	for (i=0; outstanding > (int)app.client.job_window && i<100; ++i) {
 	    pjsip_endpt_handle_events(app.sip_endpt, &timeout);
 	    outstanding = app.client.job_submitted - app.client.job_finished;
 	}
 
+
+	/* Submit one job */
 	if (app.client.method.id == PJSIP_INVITE_METHOD) {
 	    status = make_call(&app.client.dst_uri);
@@ -1259,9 +1290,13 @@
 	++app.client.job_submitted;
 
-	for (i=0; i<2; ++i) {
-	    unsigned cnt=0;
-	    pjsip_endpt_handle_events2(app.sip_endpt, &timeout, &cnt);
-	    if (cnt==0)
+	/* Handle event */
+	pjsip_endpt_handle_events2(app.sip_endpt, &timeout, NULL);
+
+	/* Check for time out */
+	if (app.client.job_submitted - last_timeout_check >= 2000) {
+	    pj_gettimeofday(&now);
+	    if (PJ_TIME_VAL_GTE(now, end_time))
 		break;
+	    last_timeout_check = app.client.job_submitted;
 	}
     }
@@ -1272,9 +1307,6 @@
 	unsigned i;
 
-	for (i=0; i<2; ++i) {
-	    unsigned cnt=0;
-	    pjsip_endpt_handle_events2(app.sip_endpt, &timeout, &cnt);
-	    if (cnt==0)
-		break;
+	for (i=0; i<2000; ++i) {
+	    pjsip_endpt_handle_events2(app.sip_endpt, &timeout, NULL);
 	}
 
@@ -1353,5 +1385,5 @@
 		good_number(str_call, app.server.cur_state.call_cnt);
 
-		printf("Total(rate): stateless:%s (%d/s), statefull:%s (%d/s), call:%s (%d/s)\r",
+		printf("Total(rate): stateless:%s (%d/s), statefull:%s (%d/s), call:%s (%d/s)       \r",
 		       str_stateless, stateless*1000/msec,
 		       str_stateful, stateful*1000/msec,
@@ -1367,6 +1399,18 @@
 }
 
+static void write_report(const char *msg)
+{
+    puts(msg);
+
+#if defined(PJ_WIN32) && PJ_WIN32!=0
+    OutputDebugString(msg);
+    OutputDebugString("\n");
+#endif
+}
+
+
 int main(int argc, char *argv[])
 {
+    static char report[1024];
 
     if (create_app() != 0)
@@ -1459,22 +1503,31 @@
 	if (msec == 0) msec = 1;
 
-	printf("Total %d %s sent, %d responses received in %d msec:\n"
-	       " - 2xx responses:  %7d (rate=%d/sec)\n"
-	       " - 3xx responses:  %7d (rate=%d/sec)\n"
-	       " - 4xx responses:  %7d (rate=%d/sec)\n"
-	       " - 5xx responses:  %7d (rate=%d/sec)\n"
-	       " - 6xx responses:  %7d (rate=%d/sec)\n"
-	       " - 7xx responses:  %7d (rate=%d/sec)\n"
-	       "                       ----------------\n"
-	       " TOTAL responses:  %7d (rate=%d/sec)\n",
-	       app.client.job_submitted, test_type,
-	       app.client.total_responses, msec,
-	       app.client.status_class[2], app.client.status_class[2]*1000/msec,
-	       app.client.status_class[3], app.client.status_class[3]*1000/msec,
-	       app.client.status_class[4], app.client.status_class[4]*1000/msec,
-	       app.client.status_class[5], app.client.status_class[5]*1000/msec,
-	       app.client.status_class[6], app.client.status_class[6]*1000/msec,
-	       app.client.status_class[7], app.client.status_class[7]*1000/msec,
-	       app.client.total_responses, app.client.total_responses*1000/msec);
+	pj_ansi_snprintf(
+	    report, sizeof(report),
+	    "Total %d %s sent, %d responses received in %d ms:\n"
+	    " - 2xx responses:  %7d (rate=%d/sec)\n"
+	    " - 3xx responses:  %7d (rate=%d/sec)\n"
+	    " - 4xx responses:  %7d (rate=%d/sec)\n"
+	    " - 5xx responses:  %7d (rate=%d/sec)\n"
+	    " - 6xx responses:  %7d (rate=%d/sec)\n"
+	    " - 7xx responses:  %7d (rate=%d/sec)\n"
+	    "                       ----------------\n"
+	    " TOTAL responses:  %7d (rate=%d/sec)\n",
+	    app.client.job_submitted, test_type,
+	    app.client.total_responses, msec,
+	    app.client.status_class[2], app.client.status_class[2]*1000/msec,
+	    app.client.status_class[3], app.client.status_class[3]*1000/msec,
+	    app.client.status_class[4], app.client.status_class[4]*1000/msec,
+	    app.client.status_class[5], app.client.status_class[5]*1000/msec,
+	    app.client.status_class[6], app.client.status_class[6]*1000/msec,
+	    app.client.status_class[7], app.client.status_class[7]*1000/msec,
+	    app.client.total_responses, app.client.total_responses*1000/msec);
+
+	write_report(report);
+
+	pj_ansi_sprintf(report, "Maximum outstanding job: %d", 
+			app.client.stat_max_window);
+	write_report(report);
+
 
     } else {
