aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2023-07-04 15:19:49 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2023-07-04 15:32:38 +0300
commit54b2a78b366517bf986afdc95b7107e8828e1794 (patch)
tree29f1797d6225680bf31fb6f0363058f614d9cfda
parenta5cf04b5d0cbaa4f51e54763e4a8e72c02751e48 (diff)
downloadlibmicrohttpd-54b2a78b366517bf986afdc95b7107e8828e1794.tar.gz
libmicrohttpd-54b2a78b366517bf986afdc95b7107e8828e1794.zip
perf_replies: added more features
-rw-r--r--configure.ac10
-rw-r--r--src/tools/Makefile.am2
-rw-r--r--src/tools/perf_replies.c262
3 files changed, 210 insertions, 64 deletions
diff --git a/configure.ac b/configure.ac
index 5d9ac157..65a700fb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3917,16 +3917,6 @@ AS_VAR_IF([enable_tools],["yes"],
3917 ) 3917 )
3918 ] 3918 ]
3919 ) 3919 )
3920 MATH_LIB=''
3921 MHD_FIND_LIB([sqrt],[#include <math.h>],
3922 [[
3923 double res = sqrt ((double) 4);
3924 i][f (((double) 2) != res) return 2;
3925 ]],[m],
3926 [AC_DEFINE([[HAVE_SQRT_FUNC]],[[1]],[Define to 1 i][f 'sqrt()' function is available.])
3927 ],[],[MATH_LIB]
3928 )
3929 AC_SUBST([MATH_LIB])
3930 ] 3920 ]
3931) 3921)
3932 3922
diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am
index d9461cd1..427c659f 100644
--- a/src/tools/Makefile.am
+++ b/src/tools/Makefile.am
@@ -37,5 +37,3 @@ endif
37 37
38perf_replies_SOURCES = \ 38perf_replies_SOURCES = \
39 perf_replies.c 39 perf_replies.c
40perf_replies_LDADD = \
41 $(LDADD) $(MATH_LIB)
diff --git a/src/tools/perf_replies.c b/src/tools/perf_replies.c
index fdfd6086..0f890941 100644
--- a/src/tools/perf_replies.c
+++ b/src/tools/perf_replies.c
@@ -334,11 +334,19 @@ show_help (void)
334 printf (" -t NUM, --threads=NUM use NUM threads\n"); 334 printf (" -t NUM, --threads=NUM use NUM threads\n");
335 printf ("\n"); 335 printf ("\n");
336 printf ("Force polling function (mutually exclusive):\n"); 336 printf ("Force polling function (mutually exclusive):\n");
337 printf (" --epoll use 'epoll' functionality\n"); 337 if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_EPOLL))
338 printf (" --poll use poll() function\n"); 338 printf (" --epoll use 'epoll' functionality\n");
339 if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_POLL))
340 printf (" --poll use poll() function\n");
339 printf (" --select use select() function\n"); 341 printf (" --select use select() function\n");
340 printf ("\n"); 342 printf ("\n");
341 printf ("Other options:\n"); 343 printf ("Other options:\n");
344 printf (" -c NUM, --connections=NUM reject more than NUM client \n"
345 " connections\n");
346 printf (" -O NUM, --timeout=NUM set connection timeout to NUM seconds,\n"
347 " zero means no timeout");
348 printf (" --date-header use the 'Date:' header in every\n"
349 " reply\n");
342 printf (" --help display this help and exit\n"); 350 printf (" --help display this help and exit\n");
343 printf (" -V, --version output version information and exit\n"); 351 printf (" -V, --version output version information and exit\n");
344 printf ("\n"); 352 printf ("\n");
@@ -355,6 +363,9 @@ struct PerfRepl_parameters
355 int epoll; 363 int epoll;
356 int poll; 364 int poll;
357 int select; 365 int select;
366 unsigned int connections;
367 unsigned int timeout;
368 int date_header;
358 int help; 369 int help;
359 int version; 370 int version;
360}; 371};
@@ -367,6 +378,9 @@ static struct PerfRepl_parameters tool_params = {
367 0, 378 0,
368 0, 379 0,
369 0, 380 0,
381 0,
382 0,
383 0,
370 0 384 0
371}; 385};
372 386
@@ -374,7 +388,7 @@ static struct PerfRepl_parameters tool_params = {
374 * Process parameter '-t' or '--threads' 388 * Process parameter '-t' or '--threads'
375 * @param param_name the name of the parameter as specified in command line 389 * @param param_name the name of the parameter as specified in command line
376 * @param param_tail the pointer to the character after parameter name in 390 * @param param_tail the pointer to the character after parameter name in
377 * the parameter string or NULL for "long" parameters 391 * the parameter string
378 * @param next_param the pointer to the next parameter (if any) or NULL 392 * @param next_param the pointer to the next parameter (if any) or NULL
379 * @return enum value, the PERF_PERPL_SPARAM_ONE_CHAR is not used by 393 * @return enum value, the PERF_PERPL_SPARAM_ONE_CHAR is not used by
380 * this function 394 * this function
@@ -424,28 +438,6 @@ process_param__all_cpus (const char *param_name)
424 438
425 439
426static enum PerfRepl_param_result 440static enum PerfRepl_param_result
427process_param__help (const char *param_name)
428{
429 /* Use only one of help | version */
430 if (! tool_params.version)
431 tool_params.help = ! 0;
432 return '-' == param_name[1] ?
433 PERF_RPL_PARAM_FULL_STR :PERF_RPL_PARAM_ONE_CHAR;
434}
435
436
437static enum PerfRepl_param_result
438process_param__version (const char *param_name)
439{
440 /* Use only one of help | version */
441 if (! tool_params.help)
442 tool_params.version = ! 0;
443 return '-' == param_name[1] ?
444 PERF_RPL_PARAM_FULL_STR :PERF_RPL_PARAM_ONE_CHAR;
445}
446
447
448static enum PerfRepl_param_result
449process_param__epoll (const char *param_name) 441process_param__epoll (const char *param_name)
450{ 442{
451 if (tool_params.poll) 443 if (tool_params.poll)
@@ -509,6 +501,95 @@ process_param__select (const char *param_name)
509 501
510 502
511/** 503/**
504 * Process parameter '-c' or '--connections'
505 * @param param_name the name of the parameter as specified in command line
506 * @param param_tail the pointer to the character after parameter name in
507 * the parameter string
508 * @param next_param the pointer to the next parameter (if any) or NULL
509 * @return enum value, the PERF_PERPL_SPARAM_ONE_CHAR is not used by
510 * this function
511 */
512static enum PerfRepl_param_result
513process_param__connections (const char *param_name, const char *param_tail,
514 const char *next_param)
515{
516 unsigned int param_value;
517 enum PerfRepl_param_result value_res;
518
519 value_res = get_param_value (param_name, param_tail, next_param,
520 &param_value);
521 if (PERF_RPL_PARAM_ERROR == value_res)
522 return value_res;
523
524 if (0 == param_value)
525 {
526 fprintf (stderr, "'0' is not valid value for parameter '%s'.\n",
527 param_name);
528 return PERF_RPL_PARAM_ERROR;
529 }
530 tool_params.connections = param_value;
531 return value_res;
532}
533
534
535/**
536 * Process parameter '-O' or '--timeout'
537 * @param param_name the name of the parameter as specified in command line
538 * @param param_tail the pointer to the character after parameter name in
539 * the parameter string
540 * @param next_param the pointer to the next parameter (if any) or NULL
541 * @return enum value, the PERF_PERPL_SPARAM_ONE_CHAR is not used by
542 * this function
543 */
544static enum PerfRepl_param_result
545process_param__timeout (const char *param_name, const char *param_tail,
546 const char *next_param)
547{
548 unsigned int param_value;
549 enum PerfRepl_param_result value_res;
550
551 value_res = get_param_value (param_name, param_tail, next_param,
552 &param_value);
553 if (PERF_RPL_PARAM_ERROR == value_res)
554 return value_res;
555
556 tool_params.timeout = param_value;
557 return value_res;
558}
559
560
561static enum PerfRepl_param_result
562process_param__date_header (const char *param_name)
563{
564 tool_params.date_header = ! 0;
565 return '-' == param_name[1] ?
566 PERF_RPL_PARAM_FULL_STR :PERF_RPL_PARAM_ONE_CHAR;
567}
568
569
570static enum PerfRepl_param_result
571process_param__help (const char *param_name)
572{
573 /* Use only one of help | version */
574 if (! tool_params.version)
575 tool_params.help = ! 0;
576 return '-' == param_name[1] ?
577 PERF_RPL_PARAM_FULL_STR :PERF_RPL_PARAM_ONE_CHAR;
578}
579
580
581static enum PerfRepl_param_result
582process_param__version (const char *param_name)
583{
584 /* Use only one of help | version */
585 if (! tool_params.help)
586 tool_params.version = ! 0;
587 return '-' == param_name[1] ?
588 PERF_RPL_PARAM_FULL_STR :PERF_RPL_PARAM_ONE_CHAR;
589}
590
591
592/**
512 * Process "short" (one character) parameter. 593 * Process "short" (one character) parameter.
513 * @param param the pointer to character after "-" or after another valid 594 * @param param the pointer to character after "-" or after another valid
514 * parameter 595 * parameter
@@ -524,6 +605,10 @@ process_short_param (const char *param, const char *next_param)
524 return process_param__all_cpus ("-A"); 605 return process_param__all_cpus ("-A");
525 else if ('t' == param_chr) 606 else if ('t' == param_chr)
526 return process_param__threads ("-t", param + 1, next_param); 607 return process_param__threads ("-t", param + 1, next_param);
608 else if ('c' == param_chr)
609 return process_param__connections ("-c", param + 1, next_param);
610 else if ('O' == param_chr)
611 return process_param__timeout ("-O", param + 1, next_param);
527 else if ('V' == param_chr) 612 else if ('V' == param_chr)
528 return process_param__version ("-V"); 613 return process_param__version ("-V");
529 614
@@ -588,6 +673,23 @@ process_long_param (const char *param, const char *next_param)
588 else if ((MHD_STATICSTR_LEN_ ("select") == param_len) && 673 else if ((MHD_STATICSTR_LEN_ ("select") == param_len) &&
589 (0 == memcmp (param, "select", MHD_STATICSTR_LEN_ ("select")))) 674 (0 == memcmp (param, "select", MHD_STATICSTR_LEN_ ("select"))))
590 return process_param__select ("--select"); 675 return process_param__select ("--select");
676 else if ((MHD_STATICSTR_LEN_ ("connections") <= param_len) &&
677 (0 == memcmp (param, "connections",
678 MHD_STATICSTR_LEN_ ("connections"))))
679 return process_param__connections ("--connections",
680 param
681 + MHD_STATICSTR_LEN_ ("connections"),
682 next_param);
683 else if ((MHD_STATICSTR_LEN_ ("timeout") <= param_len) &&
684 (0 == memcmp (param, "timeout",
685 MHD_STATICSTR_LEN_ ("timeout"))))
686 return process_param__timeout ("--timeout",
687 param + MHD_STATICSTR_LEN_ ("timeout"),
688 next_param);
689 else if ((MHD_STATICSTR_LEN_ ("date-header") == param_len) &&
690 (0 == memcmp (param, "date-header",
691 MHD_STATICSTR_LEN_ ("date-header"))))
692 return process_param__date_header ("--date-header");
591 else if ((MHD_STATICSTR_LEN_ ("help") == param_len) && 693 else if ((MHD_STATICSTR_LEN_ ("help") == param_len) &&
592 (0 == memcmp (param, "help", MHD_STATICSTR_LEN_ ("help")))) 694 (0 == memcmp (param, "help", MHD_STATICSTR_LEN_ ("help"))))
593 return process_param__help ("--help"); 695 return process_param__help ("--help");
@@ -692,6 +794,21 @@ print_all_cores_used (void)
692 794
693 795
694/** 796/**
797 * Apply parameter '-A' or '--all-cpus'
798 */
799static void
800check_apply_param__all_cpus (void)
801{
802 if (! tool_params.all_cpus)
803 return;
804
805 num_threads = get_cpu_core_count ();
806 printf ("Requested use of all available CPU cores for MHD threads.\n");
807 print_all_cores_used ();
808}
809
810
811/**
695 * Apply parameter '-t' or '--threads' 812 * Apply parameter '-t' or '--threads'
696 */ 813 */
697static void 814static void
@@ -718,21 +835,6 @@ check_apply_param__threads (void)
718} 835}
719 836
720 837
721/**
722 * Apply parameter '-A' or '--all-cpus'
723 */
724static void
725check_apply_param__all_cpus (void)
726{
727 if (! tool_params.all_cpus)
728 return;
729
730 num_threads = get_cpu_core_count ();
731 printf ("Requested use of all available CPU cores for MHD threads.\n");
732 print_all_cores_used ();
733}
734
735
736static void 838static void
737check_param_port (void) 839check_param_port (void)
738{ 840{
@@ -775,6 +877,25 @@ check_param__poll (void)
775} 877}
776 878
777 879
880/* Must be called after 'check_apply_param__threads()' and
881 'check_apply_param__all_cpus()' */
882/* non-zero - OK, zero - error */
883static int
884check_param__connections (void)
885{
886 if (0 == tool_params.connections)
887 return ! 0;
888 if (get_num_threads () > tool_params.connections)
889 {
890 fprintf (stderr, "The connections number limit (%u) is less than number "
891 "of threads used (%u). Use higher value for connections limit.\n",
892 tool_params.connections, get_num_threads ());
893 return 0;
894 }
895 return ! 0;
896}
897
898
778/** 899/**
779 * Apply decoded parameters 900 * Apply decoded parameters
780 * @return 0 if success, 901 * @return 0 if success,
@@ -794,12 +915,15 @@ check_apply_params (void)
794 print_version (); 915 print_version ();
795 return -1; 916 return -1;
796 } 917 }
918 check_param_port ();
919 check_apply_param__all_cpus ();
920 check_apply_param__threads ();
797 if (! check_param__epoll ()) 921 if (! check_param__epoll ())
798 return PERF_RPL_ERR_CODE_BAD_PARAM; 922 return PERF_RPL_ERR_CODE_BAD_PARAM;
799 if (! check_param__poll ()) 923 if (! check_param__poll ())
800 return PERF_RPL_ERR_CODE_BAD_PARAM; 924 return PERF_RPL_ERR_CODE_BAD_PARAM;
801 check_apply_param__threads (); 925 if (! check_param__connections ())
802 check_apply_param__all_cpus (); 926 return PERF_RPL_ERR_CODE_BAD_PARAM;
803 return 0; 927 return 0;
804} 928}
805 929
@@ -897,6 +1021,28 @@ answer_shared_response (void *cls,
897} 1021}
898 1022
899 1023
1024/* Borrowed from daemon.c */
1025/* TODO: run-time detection */
1026/**
1027 * Default connection limit.
1028 */
1029#ifdef MHD_POSIX_SOCKETS
1030#define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 4)
1031#else
1032#define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 2)
1033#endif
1034
1035static unsigned int
1036get_mhd_conn_limit (struct MHD_Daemon *d)
1037{
1038 /* TODO: implement run-time detection */
1039 (void) d; /* Unused */
1040 if (0 != tool_params.connections)
1041 return tool_params.connections;
1042 return (unsigned int) MHD_MAX_CONNECTIONS_DEFAULT;
1043}
1044
1045
900static int 1046static int
901run_mhd (void) 1047run_mhd (void)
902{ 1048{
@@ -935,18 +1081,25 @@ run_mhd (void)
935 (void) flags; /* No special additional flag */ 1081 (void) flags; /* No special additional flag */
936 else 1082 else
937 flags |= MHD_USE_AUTO; 1083 flags |= MHD_USE_AUTO;
938 flags |= MHD_USE_SUPPRESS_DATE_NO_CLOCK; 1084 if (! tool_params.date_header)
1085 flags |= MHD_USE_SUPPRESS_DATE_NO_CLOCK;
939 1086
940 if (0) 1087 if (0 != tool_params.connections)
941 { 1088 {
942 struct MHD_OptionItem option = 1089 struct MHD_OptionItem option =
943 { MHD_OPTION_CONNECTION_LIMIT, 5, NULL }; 1090 { MHD_OPTION_CONNECTION_LIMIT, (intptr_t) tool_params.connections, NULL };
944 opt_arr[opt_count++] = option; 1091 opt_arr[opt_count++] = option;
945 } 1092 }
946 if (1 < get_num_threads ()) 1093 if (1 < get_num_threads ())
947 { 1094 {
948 struct MHD_OptionItem option = 1095 struct MHD_OptionItem option =
949 { MHD_OPTION_THREAD_POOL_SIZE, (int) get_num_threads (), NULL }; 1096 { MHD_OPTION_THREAD_POOL_SIZE, (intptr_t) get_num_threads (), NULL };
1097 opt_arr[opt_count++] = option;
1098 }
1099 if (1)
1100 {
1101 struct MHD_OptionItem option =
1102 { MHD_OPTION_CONNECTION_TIMEOUT, (intptr_t) tool_params.timeout, NULL };
950 opt_arr[opt_count++] = option; 1103 opt_arr[opt_count++] = option;
951 } 1104 }
952 if (1) 1105 if (1)
@@ -983,17 +1136,22 @@ run_mhd (void)
983 "port number explicitly.\n"); 1136 "port number explicitly.\n");
984 1137
985 printf ("\nMHD is running.\n"); 1138 printf ("\nMHD is running.\n");
986 printf (" Bind port: %u\n", (unsigned int) port); 1139 printf (" Bind port: %u\n", (unsigned int) port);
987 printf (" Polling function: %s\n", poll_mode); 1140 printf (" Polling function: %s\n", poll_mode);
988 printf (" Threading: "); 1141 printf (" Threading: ");
989 if (1 == get_num_threads ()) 1142 if (1 == get_num_threads ())
990 printf ("one MHD thread\n"); 1143 printf ("one MHD thread\n");
991 else 1144 else
992 printf ("%u MHD threads in thread pool\n", get_num_threads ()); 1145 printf ("%u MHD threads in thread pool\n", get_num_threads ());
993 printf ("To test with remote client use http://HOST_IP:%u/\n", 1146 printf (" Connections limit: %u\n", get_mhd_conn_limit (d));
994 (unsigned int) port); 1147 printf (" Connection timeout: %u%s\n", tool_params.timeout,
1148 0 == tool_params.timeout ? " (no timeout)" : "");
1149 printf (" 'Date:' header: %s\n",
1150 tool_params.date_header ? "Yes" : "No");
1151 printf ("To test with remote client use "
1152 "http://HOST_IP:%u/\n", (unsigned int) port);
995 printf ("To test with client on the same host use " 1153 printf ("To test with client on the same host use "
996 "http://127.0.0.1:%u\n", (unsigned int) port); 1154 "http://127.0.0.1:%u/\n", (unsigned int) port);
997 printf ("\nPress ENTER to stop.\n"); 1155 printf ("\nPress ENTER to stop.\n");
998 if (1) 1156 if (1)
999 { 1157 {