aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2023-07-10 08:32:00 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2023-07-10 08:32:15 +0300
commitf586f2e7c1ebb471a76e24315783412dce2d0fec (patch)
tree63e82010393d631e86a2cfd055984e50549a760c
parent36f1c42d5f2c72e178033f676c2c24b638a067ae (diff)
downloadlibmicrohttpd-f586f2e7c1ebb471a76e24315783412dce2d0fec.tar.gz
libmicrohttpd-f586f2e7c1ebb471a76e24315783412dce2d0fec.zip
perf_replies: added options for response sharing types
-rw-r--r--src/tools/perf_replies.c502
1 files changed, 424 insertions, 78 deletions
diff --git a/src/tools/perf_replies.c b/src/tools/perf_replies.c
index 58000338..49a7a1f2 100644
--- a/src/tools/perf_replies.c
+++ b/src/tools/perf_replies.c
@@ -71,9 +71,6 @@ static const char *const build_revision = ""
71/* Dynamic variables */ 71/* Dynamic variables */
72static char self_name[500] = "perf_replies"; 72static char self_name[500] = "perf_replies";
73static uint16_t mhd_port = 0; 73static uint16_t mhd_port = 0;
74static struct MHD_Response **resps = NULL;
75static unsigned int num_resps = 0;
76static char *body_dyn = NULL; /* Non-static body data */
77 74
78static void 75static void
79set_self_name (int argc, char *const *argv) 76set_self_name (int argc, char *const *argv)
@@ -350,6 +347,14 @@ show_help (void)
350 printf (" -M, --medium medium response, 8 KB\n"); 347 printf (" -M, --medium medium response, 8 KB\n");
351 printf (" -L, --large large response, 1 MB\n"); 348 printf (" -L, --large large response, 1 MB\n");
352 printf ("\n"); 349 printf ("\n");
350 printf ("Response use options (mutually exclusive):\n");
351 printf (" -S, --shared pool of pre-generated shared response\n"
352 " objects (default)\n");
353 printf (" -I, --single single pre-generated response object\n"
354 " used for all requests\n");
355 printf (" -U, --unique response object generated for every\n"
356 " request and used one time only\n");
357 printf ("\n");
353 printf ("Other options:\n"); 358 printf ("Other options:\n");
354 printf (" -c NUM, --connections=NUM reject more than NUM client \n" 359 printf (" -c NUM, --connections=NUM reject more than NUM client \n"
355 " connections\n"); 360 " connections\n");
@@ -378,6 +383,9 @@ struct PerfRepl_parameters
378 int tiny; 383 int tiny;
379 int medium; 384 int medium;
380 int large; 385 int large;
386 int shared;
387 int single;
388 int unique;
381 unsigned int connections; 389 unsigned int connections;
382 unsigned int timeout; 390 unsigned int timeout;
383 int date_header; 391 int date_header;
@@ -401,6 +409,9 @@ static struct PerfRepl_parameters tool_params = {
401 0, 409 0,
402 0, 410 0,
403 0, 411 0,
412 0,
413 0,
414 0,
404 0 415 0
405}; 416};
406 417
@@ -662,6 +673,69 @@ process_param__large (const char *param_name)
662} 673}
663 674
664 675
676static enum PerfRepl_param_result
677process_param__shared (const char *param_name)
678{
679 if (tool_params.single)
680 {
681 fprintf (stderr, "Parameter '%s' cannot be used together "
682 "with '-I' or '--single'.\n", param_name);
683 return PERF_RPL_PARAM_ERROR;
684 }
685 if (tool_params.unique)
686 {
687 fprintf (stderr, "Parameter '%s' cannot be used together "
688 "with '-U' or '--unique'.\n", param_name);
689 return PERF_RPL_PARAM_ERROR;
690 }
691 tool_params.shared = ! 0;
692 return '-' == param_name[1] ?
693 PERF_RPL_PARAM_FULL_STR :PERF_RPL_PARAM_ONE_CHAR;
694}
695
696
697static enum PerfRepl_param_result
698process_param__single (const char *param_name)
699{
700 if (tool_params.shared)
701 {
702 fprintf (stderr, "Parameter '%s' cannot be used together "
703 "with '-S' or '--shared'.\n", param_name);
704 return PERF_RPL_PARAM_ERROR;
705 }
706 if (tool_params.unique)
707 {
708 fprintf (stderr, "Parameter '%s' cannot be used together "
709 "with '-U' or '--unique'.\n", param_name);
710 return PERF_RPL_PARAM_ERROR;
711 }
712 tool_params.single = ! 0;
713 return '-' == param_name[1] ?
714 PERF_RPL_PARAM_FULL_STR :PERF_RPL_PARAM_ONE_CHAR;
715}
716
717
718static enum PerfRepl_param_result
719process_param__unique (const char *param_name)
720{
721 if (tool_params.shared)
722 {
723 fprintf (stderr, "Parameter '%s' cannot be used together "
724 "with '-S' or '--shared'.\n", param_name);
725 return PERF_RPL_PARAM_ERROR;
726 }
727 if (tool_params.single)
728 {
729 fprintf (stderr, "Parameter '%s' cannot be used together "
730 "with '-I' or '--single'.\n", param_name);
731 return PERF_RPL_PARAM_ERROR;
732 }
733 tool_params.unique = ! 0;
734 return '-' == param_name[1] ?
735 PERF_RPL_PARAM_FULL_STR :PERF_RPL_PARAM_ONE_CHAR;
736}
737
738
665/** 739/**
666 * Process parameter '-c' or '--connections' 740 * Process parameter '-c' or '--connections'
667 * @param param_name the name of the parameter as specified in command line 741 * @param param_name the name of the parameter as specified in command line
@@ -783,6 +857,12 @@ process_short_param (const char *param, const char *next_param)
783 return process_param__medium ("-M"); 857 return process_param__medium ("-M");
784 else if ('L' == param_chr) 858 else if ('L' == param_chr)
785 return process_param__large ("-L"); 859 return process_param__large ("-L");
860 else if ('S' == param_chr)
861 return process_param__shared ("-S");
862 else if ('I' == param_chr)
863 return process_param__single ("-I");
864 else if ('U' == param_chr)
865 return process_param__unique ("-U");
786 else if ('c' == param_chr) 866 else if ('c' == param_chr)
787 return process_param__connections ("-c", param + 1, next_param); 867 return process_param__connections ("-c", param + 1, next_param);
788 else if ('O' == param_chr) 868 else if ('O' == param_chr)
@@ -867,6 +947,15 @@ process_long_param (const char *param, const char *next_param)
867 else if ((MHD_STATICSTR_LEN_ ("large") == param_len) && 947 else if ((MHD_STATICSTR_LEN_ ("large") == param_len) &&
868 (0 == memcmp (param, "large", MHD_STATICSTR_LEN_ ("large")))) 948 (0 == memcmp (param, "large", MHD_STATICSTR_LEN_ ("large"))))
869 return process_param__large ("--large"); 949 return process_param__large ("--large");
950 else if ((MHD_STATICSTR_LEN_ ("shared") == param_len) &&
951 (0 == memcmp (param, "shared", MHD_STATICSTR_LEN_ ("shared"))))
952 return process_param__shared ("--shared");
953 else if ((MHD_STATICSTR_LEN_ ("single") == param_len) &&
954 (0 == memcmp (param, "single", MHD_STATICSTR_LEN_ ("single"))))
955 return process_param__single ("--single");
956 else if ((MHD_STATICSTR_LEN_ ("unique") == param_len) &&
957 (0 == memcmp (param, "unique", MHD_STATICSTR_LEN_ ("unique"))))
958 return process_param__unique ("--unique");
870 else if ((MHD_STATICSTR_LEN_ ("connections") <= param_len) && 959 else if ((MHD_STATICSTR_LEN_ ("connections") <= param_len) &&
871 (0 == memcmp (param, "connections", 960 (0 == memcmp (param, "connections",
872 MHD_STATICSTR_LEN_ ("connections")))) 961 MHD_STATICSTR_LEN_ ("connections"))))
@@ -1102,6 +1191,14 @@ check_param__empty_tiny_medium_large (void)
1102} 1191}
1103 1192
1104 1193
1194static void
1195check_param__shared_single_unique (void)
1196{
1197 if (0 == (tool_params.shared | tool_params.single | tool_params.unique))
1198 tool_params.shared = ! 0;
1199}
1200
1201
1105/* Must be called after 'check_apply_param__threads()' and 1202/* Must be called after 'check_apply_param__threads()' and
1106 'check_apply_param__all_cpus()' */ 1203 'check_apply_param__all_cpus()' */
1107/* non-zero - OK, zero - error */ 1204/* non-zero - OK, zero - error */
@@ -1150,35 +1247,36 @@ check_apply_params (void)
1150 if (! check_param__poll ()) 1247 if (! check_param__poll ())
1151 return PERF_RPL_ERR_CODE_BAD_PARAM; 1248 return PERF_RPL_ERR_CODE_BAD_PARAM;
1152 check_param__empty_tiny_medium_large (); 1249 check_param__empty_tiny_medium_large ();
1250 check_param__shared_single_unique ();
1153 if (! check_param__connections ()) 1251 if (! check_param__connections ())
1154 return PERF_RPL_ERR_CODE_BAD_PARAM; 1252 return PERF_RPL_ERR_CODE_BAD_PARAM;
1155 return 0; 1253 return 0;
1156} 1254}
1157 1255
1158 1256
1159static int 1257/* The pool of shared responses */
1160init_data (void) 1258static struct MHD_Response **resps = NULL;
1161{ 1259static unsigned int num_resps = 0;
1162 /* Use the same memory area to avoid multiple copies. 1260/* The single response */
1163 The system will keep it in cache. */ 1261static struct MHD_Response *resp_single = NULL;
1164 static const char tiny_body[] = "Hi!";
1165 unsigned int i;
1166 size_t body_dyn_size;
1167 1262
1168 if (tool_params.medium) 1263/* Use the same memory area to avoid multiple copies.
1169 body_dyn_size = 8U * 1024U; 1264 The system will keep it in cache. */
1170 else if (tool_params.large) 1265static const char tiny_body[] = "Hi!";
1171 body_dyn_size = 1024U * 1024U; 1266static char *body_dyn = NULL; /* Non-static body data */
1172 else 1267size_t body_dyn_size;
1173 body_dyn_size = 0;
1174 1268
1269/* Non-zero - success, zero - failure */
1270static int
1271init_response_body_data (void)
1272{
1175 if (0 != body_dyn_size) 1273 if (0 != body_dyn_size)
1176 { 1274 {
1177 body_dyn = (char *) malloc (body_dyn_size); 1275 body_dyn = (char *) malloc (body_dyn_size);
1178 if (NULL == body_dyn) 1276 if (NULL == body_dyn)
1179 { 1277 {
1180 fprintf (stderr, "Failed to allocate memory.\n"); 1278 fprintf (stderr, "Failed to allocate memory.\n");
1181 return 25; 1279 return 0;
1182 } 1280 }
1183 if (tool_params.medium) 1281 if (tool_params.medium)
1184 { 1282 {
@@ -1218,10 +1316,76 @@ init_data (void)
1218 } 1316 }
1219 } 1317 }
1220 } 1318 }
1319 return ! 0;
1320}
1321
1322
1323static struct MHD_Response *
1324create_response_object (void)
1325{
1326#if MHD_VERSION >= 0x00097701
1327 if (NULL != body_dyn)
1328 return MHD_create_response_from_buffer_static (body_dyn_size,
1329 body_dyn);
1330 else if (tool_params.empty)
1331 return MHD_create_response_empty (MHD_RF_NONE);
1332
1333 return MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (tiny_body),
1334 tiny_body);
1335
1336#else /* MHD_VERSION < 0x00097701 */
1337 if (NULL != body_dyn)
1338 return MHD_create_response_from_buffer (body_dyn_size,
1339 (void *) body_dyn,
1340 MHD_RESPMEM_PERSISTENT);
1341 else if (tool_params.empty)
1342 return MHD_create_response_from_buffer (0,
1343 (void *) tiny_body,
1344 MHD_RESPMEM_PERSISTENT);
1345
1346 return MHD_create_response_from_buffer (MHD_STATICSTR_LEN_ (tiny_body),
1347 (void *) tiny_body,
1348 MHD_RESPMEM_PERSISTENT);
1349#endif /* MHD_VERSION < 0x00097701 */
1350}
1351
1352
1353static int
1354init_data (void)
1355{
1356 unsigned int i;
1357
1358 if (tool_params.medium)
1359 body_dyn_size = 8U * 1024U;
1360 else if (tool_params.large)
1361 body_dyn_size = 1024U * 1024U;
1362 else
1363 body_dyn_size = 0;
1364
1365 if (! init_response_body_data ())
1366 return 25;
1367
1368 if (tool_params.unique)
1369 return 0; /* Responses are generated on-fly */
1370
1371 if (tool_params.single)
1372 {
1373 resp_single = create_response_object ();
1374 if (NULL == resp_single)
1375 {
1376 fprintf (stderr, "Failed to create response.\n");
1377 return 25;
1378 }
1379 return 0;
1380 }
1381
1382 /* Use more responses to minimise waiting in threads while the response
1383 used by other thread. */
1384 if (! tool_params.thread_per_conn)
1385 num_resps = 16 * get_num_threads ();
1386 else
1387 num_resps = 16 * get_cpu_core_count ();
1221 1388
1222 /* Use more responses to minimise waiting in threads to unlock
1223 the response used by other thread. */
1224 num_resps = 16 * get_num_threads ();
1225 resps = (struct MHD_Response **) 1389 resps = (struct MHD_Response **)
1226 malloc ((sizeof(struct MHD_Response *)) * num_resps); 1390 malloc ((sizeof(struct MHD_Response *)) * num_resps);
1227 if (NULL == resps) 1391 if (NULL == resps)
@@ -1236,33 +1400,7 @@ init_data (void)
1236 } 1400 }
1237 for (i = 0; i < num_resps; ++i) 1401 for (i = 0; i < num_resps; ++i)
1238 { 1402 {
1239#if MHD_VERSION >= 0x00097701 1403 resps[i] = create_response_object ();
1240 if (NULL != body_dyn)
1241 resps[i] = MHD_create_response_from_buffer_static (body_dyn_size,
1242 body_dyn);
1243 else if (tool_params.empty)
1244 resps[i] = MHD_create_response_empty (MHD_RF_NONE);
1245 else
1246 resps[i] =
1247 MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (tiny_body),
1248 tiny_body);
1249
1250#else /* MHD_VERSION < 0x00097701 */
1251 if (NULL != body_dyn)
1252 resps[i] = MHD_create_response_from_buffer (body_dyn_size,
1253 (void *) body_dyn,
1254 MHD_RESPMEM_PERSISTENT);
1255 else if (tool_params.empty)
1256 resps[i] = MHD_create_response_from_buffer (0,
1257 (void *) tiny_body,
1258 MHD_RESPMEM_PERSISTENT);
1259 else if (tool_params.tiny)
1260 resps[i] =
1261 MHD_create_response_from_buffer (MHD_STATICSTR_LEN_ (tiny_body),
1262 (void *) tiny_body,
1263 MHD_RESPMEM_PERSISTENT);
1264 else
1265#endif /* MHD_VERSION < 0x00097701 */
1266 if (NULL == resps[i]) 1404 if (NULL == resps[i])
1267 { 1405 {
1268 fprintf (stderr, "Failed to create responses.\n"); 1406 fprintf (stderr, "Failed to create responses.\n");
@@ -1288,13 +1426,18 @@ init_data (void)
1288static void 1426static void
1289deinit_data (void) 1427deinit_data (void)
1290{ 1428{
1291 unsigned int i; 1429 if (NULL != resp_single)
1292 for (i = 0; i < num_resps; ++i) 1430 MHD_destroy_response (resp_single);
1293 MHD_destroy_response (resps[i]); 1431 resp_single = NULL;
1294 1432 if (NULL != resps)
1295 free (resps); 1433 {
1434 unsigned int i;
1435 for (i = 0; i < num_resps; ++i)
1436 MHD_destroy_response (resps[i]);
1437 num_resps = 0;
1438 free (resps);
1439 }
1296 resps = NULL; 1440 resps = NULL;
1297 num_resps = 0;
1298 if (NULL != body_dyn) 1441 if (NULL != body_dyn)
1299 free (body_dyn); 1442 free (body_dyn);
1300 body_dyn = NULL; 1443 body_dyn = NULL;
@@ -1338,6 +1481,192 @@ answer_shared_response (void *cls,
1338} 1481}
1339 1482
1340 1483
1484static enum MHD_Result
1485answer_single_response (void *cls,
1486 struct MHD_Connection *connection,
1487 const char *url,
1488 const char *method,
1489 const char *version,
1490 const char *upload_data,
1491 size_t *upload_data_size,
1492 void **req_cls)
1493{
1494 static int marker = 0;
1495 (void) cls; /* Unused */
1496 (void) url; (void) version; /* Unused */
1497 (void) upload_data; (void) upload_data_size; /* Unused */
1498
1499 if (NULL == *req_cls)
1500 {
1501 /* The fist call */
1502 *req_cls = (void *) &marker;
1503 /* Do not send reply yet. No error. */
1504 return MHD_YES;
1505 }
1506 if ((0 != strcmp (method, MHD_HTTP_METHOD_GET)) &&
1507 (0 != strcmp (method, MHD_HTTP_METHOD_HEAD)))
1508 return MHD_NO; /* Unsupported method, close connection */
1509
1510 return MHD_queue_response (connection, MHD_HTTP_OK, resp_single);
1511}
1512
1513
1514static enum MHD_Result
1515answer_unique_empty_response (void *cls,
1516 struct MHD_Connection *connection,
1517 const char *url,
1518 const char *method,
1519 const char *version,
1520 const char *upload_data,
1521 size_t *upload_data_size,
1522 void **req_cls)
1523{
1524 static int marker = 0;
1525 struct MHD_Response *r;
1526 enum MHD_Result ret;
1527 (void) cls; /* Unused */
1528 (void) url; (void) version; /* Unused */
1529 (void) upload_data; (void) upload_data_size; /* Unused */
1530
1531 if (NULL == *req_cls)
1532 {
1533 /* The fist call */
1534 *req_cls = (void *) &marker;
1535 /* Do not send reply yet. No error. */
1536 return MHD_YES;
1537 }
1538 if ((0 != strcmp (method, MHD_HTTP_METHOD_GET)) &&
1539 (0 != strcmp (method, MHD_HTTP_METHOD_HEAD)))
1540 return MHD_NO; /* Unsupported method, close connection */
1541
1542#if MHD_VERSION >= 0x00097701
1543 r = MHD_create_response_empty (MHD_RF_NONE);
1544#else /* MHD_VERSION < 0x00097701 */
1545 r = MHD_create_response_from_buffer (0,
1546 NULL,
1547 MHD_RESPMEM_PERSISTENT);
1548#endif /* MHD_VERSION < 0x00097701 */
1549 ret = MHD_queue_response (connection, MHD_HTTP_OK, r);
1550 MHD_destroy_response (r);
1551 return ret;
1552}
1553
1554
1555static enum MHD_Result
1556answer_unique_tiny_response (void *cls,
1557 struct MHD_Connection *connection,
1558 const char *url,
1559 const char *method,
1560 const char *version,
1561 const char *upload_data,
1562 size_t *upload_data_size,
1563 void **req_cls)
1564{
1565 static int marker = 0;
1566 struct MHD_Response *r;
1567 enum MHD_Result ret;
1568 (void) cls; /* Unused */
1569 (void) url; (void) version; /* Unused */
1570 (void) upload_data; (void) upload_data_size; /* Unused */
1571
1572 if (NULL == *req_cls)
1573 {
1574 /* The fist call */
1575 *req_cls = (void *) &marker;
1576 /* Do not send reply yet. No error. */
1577 return MHD_YES;
1578 }
1579 if ((0 != strcmp (method, MHD_HTTP_METHOD_GET)) &&
1580 (0 != strcmp (method, MHD_HTTP_METHOD_HEAD)))
1581 return MHD_NO; /* Unsupported method, close connection */
1582
1583#if MHD_VERSION >= 0x00097701
1584 r = MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (tiny_body),
1585 tiny_body);
1586#else /* MHD_VERSION < 0x00097701 */
1587 r = MHD_create_response_from_buffer (MHD_STATICSTR_LEN_ (tiny_body),
1588 (void *) tiny_body,
1589 MHD_RESPMEM_PERSISTENT);
1590#endif /* MHD_VERSION < 0x00097701 */
1591 ret = MHD_queue_response (connection, MHD_HTTP_OK, r);
1592 MHD_destroy_response (r);
1593 return ret;
1594}
1595
1596
1597static enum MHD_Result
1598answer_unique_dyn_response (void *cls,
1599 struct MHD_Connection *connection,
1600 const char *url,
1601 const char *method,
1602 const char *version,
1603 const char *upload_data,
1604 size_t *upload_data_size,
1605 void **req_cls)
1606{
1607 static int marker = 0;
1608 struct MHD_Response *r;
1609 enum MHD_Result ret;
1610 (void) cls; /* Unused */
1611 (void) url; (void) version; /* Unused */
1612 (void) upload_data; (void) upload_data_size; /* Unused */
1613
1614 if (NULL == *req_cls)
1615 {
1616 /* The fist call */
1617 *req_cls = (void *) &marker;
1618 /* Do not send reply yet. No error. */
1619 return MHD_YES;
1620 }
1621 if ((0 != strcmp (method, MHD_HTTP_METHOD_GET)) &&
1622 (0 != strcmp (method, MHD_HTTP_METHOD_HEAD)))
1623 return MHD_NO; /* Unsupported method, close connection */
1624
1625#if MHD_VERSION >= 0x00097701
1626 r = MHD_create_response_from_buffer_static (body_dyn_size,
1627 body_dyn);
1628#else /* MHD_VERSION < 0x00097701 */
1629 r = MHD_create_response_from_buffer (body_dyn_size,
1630 (void *) body_dyn,
1631 MHD_RESPMEM_PERSISTENT);
1632#endif /* MHD_VERSION < 0x00097701 */
1633 ret = MHD_queue_response (connection, MHD_HTTP_OK, r);
1634 MHD_destroy_response (r);
1635 return ret;
1636}
1637
1638
1639static void
1640print_perf_warnings (void)
1641{
1642 int newline_needed = 0;
1643#if defined (_DEBUG)
1644 fprintf (stderr, "WARNING: Running with debug asserts enabled, "
1645 "the performance is suboptimal.\n");
1646 newline_needed |= ! 0;
1647#endif /* _DEBUG */
1648#if defined(__GNUC__) && ! defined (__OPTIMIZE__)
1649 fprintf (stderr, "WARNING: The tools is compiled without enabled compiler "
1650 "optimisations, the performance is suboptimal.\n");
1651 newline_needed |= ! 0;
1652#endif /* __GNUC__ && ! __OPTIMIZE__ */
1653#if defined(__GNUC__) && defined (__OPTIMIZE_SIZE__)
1654 fprintf (stderr, "WARNING: The tools is compiled with size-optimisations, "
1655 "the performance is suboptimal.\n");
1656#endif /* __GNUC__ && ! __OPTIMIZE__ */
1657#if MHD_VERSION >= 0x00097701
1658 if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_DEBUG_BUILD))
1659 {
1660 fprintf (stderr, "WARNING: The libmicrohttpd is compiled with "
1661 "debug asserts enabled, the performance is suboptimal.\n");
1662 newline_needed |= ! 0;
1663 }
1664#endif /* MHD_VERSION >= 0x00097701 */
1665 if (newline_needed)
1666 printf ("\n");
1667}
1668
1669
1341/* Borrowed from daemon.c */ 1670/* Borrowed from daemon.c */
1342/* TODO: run-time detection */ 1671/* TODO: run-time detection */
1343/** 1672/**
@@ -1379,7 +1708,9 @@ get_mhd_response_size (void)
1379static int 1708static int
1380run_mhd (void) 1709run_mhd (void)
1381{ 1710{
1711 MHD_AccessHandlerCallback reply_func;
1382 struct MHD_Daemon *d; 1712 struct MHD_Daemon *d;
1713 unsigned int use_num_threads;
1383 unsigned int flags = MHD_NO_FLAG; 1714 unsigned int flags = MHD_NO_FLAG;
1384 struct MHD_OptionItem opt_arr[16]; 1715 struct MHD_OptionItem opt_arr[16];
1385 size_t opt_count = 0; 1716 size_t opt_count = 0;
@@ -1387,23 +1718,40 @@ run_mhd (void)
1387 const char *poll_mode; 1718 const char *poll_mode;
1388 uint16_t port; 1719 uint16_t port;
1389 1720
1390#if defined (_DEBUG) 1721 if (tool_params.thread_per_conn)
1391 fprintf (stderr, "WARNING: Running with debug asserts enabled, " 1722 use_num_threads = 0;
1392 "the performance is suboptimal.\n"); 1723 else
1393#endif /* _DEBUG */ 1724 use_num_threads = get_num_threads ();
1394#if defined(__GNUC__) && ! defined (__OPTIMIZE__) 1725 printf ("\n");
1395 fprintf (stderr, "WARNING: The tools is compiled without enabled compiler " 1726
1396 "optimisations, the performance is suboptimal.\n"); 1727 print_perf_warnings ();
1397#endif /* __GNUC__ && ! __OPTIMIZE__ */ 1728
1398#if defined(__GNUC__) && defined (__OPTIMIZE_SIZE__) 1729 printf ("Responses:\n");
1399 fprintf (stderr, "WARNING: The tools is compiled with size-optimisations, " 1730 printf (" Sharing: ");
1400 "the performance is suboptimal.\n"); 1731 if (tool_params.shared)
1401#endif /* __GNUC__ && ! __OPTIMIZE__ */ 1732 {
1402#if MHD_VERSION >= 0x00097701 1733 reply_func = &answer_shared_response;
1403 if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_DEBUG_BUILD)) 1734 printf ("pre-generated shared pool with %u objects\n", num_resps);
1404 fprintf (stderr, "WARNING: The libmicrohttpd is compiled with " 1735 }
1405 "debug asserts enabled, the performance is suboptimal.\n"); 1736 else if (tool_params.single)
1406#endif /* MHD_VERSION >= 0x00097701 */ 1737 {
1738 reply_func = &answer_single_response;
1739 printf ("single pre-generated reused response object\n");
1740 }
1741 else
1742 {
1743 /* Unique responses */
1744 if (tool_params.empty)
1745 reply_func = &answer_unique_empty_response;
1746 else if (tool_params.tiny)
1747 reply_func = &answer_unique_tiny_response;
1748 else
1749 reply_func = &answer_unique_dyn_response;
1750 printf ("one-time response object generated for every request\n");
1751 }
1752 printf (" Body size: %s\n",
1753 get_mhd_response_size ());
1754
1407 flags |= MHD_USE_ERROR_LOG; 1755 flags |= MHD_USE_ERROR_LOG;
1408 flags |= MHD_USE_INTERNAL_POLLING_THREAD; 1756 flags |= MHD_USE_INTERNAL_POLLING_THREAD;
1409 if (tool_params.epoll) 1757 if (tool_params.epoll)
@@ -1427,10 +1775,10 @@ run_mhd (void)
1427 { MHD_OPTION_CONNECTION_LIMIT, (intptr_t) tool_params.connections, NULL }; 1775 { MHD_OPTION_CONNECTION_LIMIT, (intptr_t) tool_params.connections, NULL };
1428 opt_arr[opt_count++] = option; 1776 opt_arr[opt_count++] = option;
1429 } 1777 }
1430 if (1 < get_num_threads ()) 1778 if (1 < use_num_threads)
1431 { 1779 {
1432 struct MHD_OptionItem option = 1780 struct MHD_OptionItem option =
1433 { MHD_OPTION_THREAD_POOL_SIZE, (intptr_t) get_num_threads (), NULL }; 1781 { MHD_OPTION_THREAD_POOL_SIZE, (intptr_t) use_num_threads, NULL };
1434 opt_arr[opt_count++] = option; 1782 opt_arr[opt_count++] = option;
1435 } 1783 }
1436 if (1) 1784 if (1)
@@ -1447,8 +1795,8 @@ run_mhd (void)
1447 if (opt_count >= (sizeof(opt_arr) / sizeof(opt_arr[0]))) 1795 if (opt_count >= (sizeof(opt_arr) / sizeof(opt_arr[0])))
1448 abort (); 1796 abort ();
1449 } 1797 }
1450 d = MHD_start_daemon (flags, mhd_port, NULL, NULL, &answer_shared_response, 1798 d = MHD_start_daemon (flags, mhd_port, NULL, NULL, reply_func, NULL,
1451 NULL, MHD_OPTION_ARRAY, opt_arr, MHD_OPTION_END); 1799 MHD_OPTION_ARRAY, opt_arr, MHD_OPTION_END);
1452 if (NULL == d) 1800 if (NULL == d)
1453 { 1801 {
1454 fprintf (stderr, "Error starting MHD daemon.\n"); 1802 fprintf (stderr, "Error starting MHD daemon.\n");
@@ -1472,7 +1820,7 @@ run_mhd (void)
1472 fprintf (stderr, "Cannot detect port number. Consider specifying " 1820 fprintf (stderr, "Cannot detect port number. Consider specifying "
1473 "port number explicitly.\n"); 1821 "port number explicitly.\n");
1474 1822
1475 printf ("\nMHD is running.\n"); 1823 printf ("MHD is running.\n");
1476 printf (" Bind port: %u\n", (unsigned int) port); 1824 printf (" Bind port: %u\n", (unsigned int) port);
1477 printf (" Polling function: %s\n", poll_mode); 1825 printf (" Polling function: %s\n", poll_mode);
1478 printf (" Threading: "); 1826 printf (" Threading: ");
@@ -1487,8 +1835,6 @@ run_mhd (void)
1487 0 == tool_params.timeout ? " (no timeout)" : ""); 1835 0 == tool_params.timeout ? " (no timeout)" : "");
1488 printf (" 'Date:' header: %s\n", 1836 printf (" 'Date:' header: %s\n",
1489 tool_params.date_header ? "Yes" : "No"); 1837 tool_params.date_header ? "Yes" : "No");
1490 printf (" Response body size: %s\n",
1491 get_mhd_response_size ());
1492 printf ("To test with remote client use " 1838 printf ("To test with remote client use "
1493 "http://HOST_IP:%u/\n", (unsigned int) port); 1839 "http://HOST_IP:%u/\n", (unsigned int) port);
1494 printf ("To test with client on the same host use " 1840 printf ("To test with client on the same host use "