From 59b558d92885c2a3a9bb3d0ceb367db209cb08dc Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 26 Jul 2024 16:58:48 +0200 Subject: [PATCH] fix generator to special-case response options --- src/include/Makefile.am | 8 +- src/include/d_options.rec | 58 ++++++------ src/include/microhttpd2.h | 2 +- .../microhttpd2_generated_response_options.h | 22 ++--- src/include/options-generator.c | 69 ++++++++++---- src/include/r_options.rec | 2 +- src/mhd2/daemon_options.h | 5 +- src/mhd2/daemon_set_options.c | 74 +++++++-------- src/mhd2/response_options.h | 6 +- src/mhd2/response_set_options.c | 90 ++++++------------- 10 files changed, 166 insertions(+), 170 deletions(-) diff --git a/src/include/Makefile.am b/src/include/Makefile.am index fbe9afdd..266b0f85 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am @@ -5,10 +5,10 @@ microhttpd2_inline_daemon_documentation.h.in microhttpd2_generated_daemon_option rm -f microhttpd2_inline_daemon_documentation.h.in microhttpd2_generated_daemon_options.h ./options-generator daemon > microhttpd2_generated_daemon_options.h chmod -w $@ -#microhttpd2_inline_response_documentation.h.in microhttpd2_generated_response_options.h: r_options.rec options-generator -# rm -f microhttpd2_inline_response_documentation.h.in microhttpd2_generated_response_options.h -# ./options-generator response > microhttpd2_generated_response_options.h -# chmod -w $@ +microhttpd2_inline_response_documentation.h.in microhttpd2_generated_response_options.h: r_options.rec options-generator + rm -f microhttpd2_inline_response_documentation.h.in microhttpd2_generated_response_options.h + ./options-generator response > microhttpd2_generated_response_options.h + chmod -w $@ microhttpd2.h: microhttpd2_preamble.h.in microhttpd2_inline_daemon_documentation.h.in microhttpd2_inline_response_documentation.h.in microhttpd2_main.h.in microhttpd2_postamble.h.in rm -f $@ diff --git a/src/include/d_options.rec b/src/include/d_options.rec index 8eb09cb9..4d4b089b 100644 --- a/src/include/d_options.rec +++ b/src/include/d_options.rec @@ -75,20 +75,18 @@ Description2: the address to bind to; can be IPv4 (AF_INET), IPv6 (AF_INET6) or Argument3: enum MHD_Bool dual Description3: When a previous version of the protocol exist (like IPv4 when @a v_sa is IPv6) bind to both protocols (IPv6 and IPv4). CustomSetter: /* custom setter */ -+ if (0 != option->val.bind_sa.v_sa_len) -+ { -+ if (NULL != settings->bind_sa.v_sa) -+ free (settings->bind_sa.v_sa); -+ -+ settings->bind_sa.v_sa = malloc (option->val.bind_sa.v_sa_len); -+ if (NULL == settings->bind_sa.v_sa) -+ return MHD_SC_DAEMON_MALLOC_FAILURE; -+ -+ memcpy (settings->bind_sa.v_sa, option->val.bind_sa.v_sa, -+ option->val.bind_sa.v_sa_len); -+ settings->bind_sa.v_sa_len = option->val.bind_sa.v_sa_len; -+ settings->bind_sa.v_dual = option->val.bind_sa.v_dual; -+ } ++ if (0 != option->val.bind_sa.v_sa_len) ++ { ++ if (NULL != settings->bind_sa.v_sa) ++ free (settings->bind_sa.v_sa); ++ settings->bind_sa.v_sa = malloc (option->val.bind_sa.v_sa_len); ++ if (NULL == settings->bind_sa.v_sa) ++ return MHD_SC_DAEMON_MALLOC_FAILURE; ++ memcpy (settings->bind_sa.v_sa, option->val.bind_sa.v_sa, ++ option->val.bind_sa.v_sa_len); ++ settings->bind_sa.v_sa_len = option->val.bind_sa.v_sa_len; ++ settings->bind_sa.v_dual = option->val.bind_sa.v_dual; ++ } Name: listen_socket Value: 82 @@ -384,23 +382,21 @@ Argument2: /* const */ void *buf Description2: the buffer with strong random data, the content will be copied by MHD Type: struct MHD_DaemonOptionEntropySeed CustomSetter: /* custom setter */ -+ /* The is not an easy for automatic generations */ -+ if (0 != option->val.random_entropy.v_buf_size) -+ { -+ if (NULL != settings->random_entropy.v_buf) -+ free (settings->random_entropy.v_buf); -+ -+ settings->random_entropy.v_buf = -+ malloc (option->val.random_entropy.v_buf_size); -+ if (NULL == settings->random_entropy.v_buf) -+ return MHD_SC_DAEMON_MALLOC_FAILURE; -+ -+ memcpy (settings->random_entropy.v_buf, -+ option->val.random_entropy.v_buf, -+ option->val.random_entropy.v_buf_size); -+ settings->random_entropy.v_buf_size = -+ option->val.random_entropy.v_buf_size; -+ } ++ /* The is not an easy for automatic generations */ ++ if (0 != option->val.random_entropy.v_buf_size) ++ { ++ if (NULL != settings->random_entropy.v_buf) ++ free (settings->random_entropy.v_buf); ++ settings->random_entropy.v_buf = ++ malloc (option->val.random_entropy.v_buf_size); ++ if (NULL == settings->random_entropy.v_buf) ++ return MHD_SC_DAEMON_MALLOC_FAILURE; ++ memcpy (settings->random_entropy.v_buf, ++ option->val.random_entropy.v_buf, ++ option->val.random_entropy.v_buf_size); ++ settings->random_entropy.v_buf_size = ++ option->val.random_entropy.v_buf_size; ++ } Name: dauth_map_size diff --git a/src/include/microhttpd2.h b/src/include/microhttpd2.h index 370e6de8..2a8dfca8 100644 --- a/src/include/microhttpd2.h +++ b/src/include/microhttpd2.h @@ -4171,7 +4171,7 @@ MHD_D_OPTION_DAUTH_DEF_MAX_NC ( #if 0 /** - * Make the response object re-usable. + * Make the response object re-usable. (FIXME: not used in struct ResponseOptions; remove!?) * The response will not be consumed by MHD_action_from_response() and must be destroyed by MHD_response_destroy(). * Useful if the same response is often used to reply. * @param val the value of the parameter * @return structure with the requested setting diff --git a/src/include/microhttpd2_generated_response_options.h b/src/include/microhttpd2_generated_response_options.h index 3882b562..60879632 100644 --- a/src/include/microhttpd2_generated_response_options.h +++ b/src/include/microhttpd2_generated_response_options.h @@ -11,7 +11,7 @@ enum MHD_FIXED_ENUM_APP_SET_ MHD_ResponseOption , /** - * Make the response object re-usable. + * Make the response object re-usable. (FIXME: not used in struct ResponseOptions; remove!?) * The response will not be consumed by MHD_action_from_response() and must be destroyed by MHD_response_destroy(). * Useful if the same response is often used to reply. */ @@ -178,7 +178,7 @@ struct MHD_ResponseOptionAndValue #if defined(MHD_USE_COMPOUND_LITERALS) && defined(MHD_USE_DESIG_NEST_INIT) /** - * Make the response object re-usable. + * Make the response object re-usable. (FIXME: not used in struct ResponseOptions; remove!?) * The response will not be consumed by MHD_action_from_response() and must be destroyed by MHD_response_destroy(). * Useful if the same response is often used to reply. * @param val the value of the parameter * @return structure with the requested setting @@ -321,12 +321,12 @@ With this option HTTP/1.0 server is emulated (with support for 'keep-alive' conn #else /* !MHD_USE_COMPOUND_LITERALS || !MHD_USE_DESIG_NEST_INIT */ MHD_NOWARN_UNUSED_FUNC_ /** - * Make the response object re-usable. + * Make the response object re-usable. (FIXME: not used in struct ResponseOptions; remove!?) * The response will not be consumed by MHD_action_from_response() and must be destroyed by MHD_response_destroy(). * Useful if the same response is often used to reply. * @param val the value of the parameter * @return structure with the requested setting */ -static MHD_INLINE struct MHD_responseOptionAndValue +static MHD_INLINE struct MHD_ResponseOptionAndValue MHD_R_OPTION_REUSABLE ( enum MHD_Bool val ) @@ -348,7 +348,7 @@ MHD_R_OPTION_REUSABLE ( * This flag is primarily intended to be used when automatic 'Content-Length' header is undesirable in response to HEAD requests. * @param val the value of the parameter * @return structure with the requested setting */ -static MHD_INLINE struct MHD_responseOptionAndValue +static MHD_INLINE struct MHD_ResponseOptionAndValue MHD_R_OPTION_HEAD_ONLY_RESPONSE ( enum MHD_Bool val ) @@ -367,7 +367,7 @@ MHD_R_OPTION_HEAD_ONLY_RESPONSE ( * Ignored when the reply cannot have body/content. * @param val the value of the parameter * @return structure with the requested setting */ -static MHD_INLINE struct MHD_responseOptionAndValue +static MHD_INLINE struct MHD_ResponseOptionAndValue MHD_R_OPTION_CHUNKED_ENC ( enum MHD_Bool val ) @@ -385,7 +385,7 @@ MHD_R_OPTION_CHUNKED_ENC ( * Force close connection after sending the response, prevents keep-alive connections and adds 'Connection: close' header. * @param val the value of the parameter * @return structure with the requested setting */ -static MHD_INLINE struct MHD_responseOptionAndValue +static MHD_INLINE struct MHD_ResponseOptionAndValue MHD_R_OPTION_CONN_CLOSE ( enum MHD_Bool val ) @@ -412,7 +412,7 @@ MHD_R_OPTION_CONN_CLOSE ( This option can be used to communicate with some broken client, which does not implement HTTP/1.1 features, but advertises HTTP/1.1 support. * @param val the value of the parameter * @return structure with the requested setting */ -static MHD_INLINE struct MHD_responseOptionAndValue +static MHD_INLINE struct MHD_ResponseOptionAndValue MHD_R_OPTION_HTTP_1_0_COMPATIBLE_STRICT ( enum MHD_Bool val ) @@ -441,7 +441,7 @@ MHD_R_OPTION_HTTP_1_0_COMPATIBLE_STRICT ( With this option HTTP/1.0 server is emulated (with support for 'keep-alive' connections). * @param val the value of the parameter * @return structure with the requested setting */ -static MHD_INLINE struct MHD_responseOptionAndValue +static MHD_INLINE struct MHD_ResponseOptionAndValue MHD_R_OPTION_HTTP_1_0_SERVER ( enum MHD_Bool val ) @@ -460,7 +460,7 @@ MHD_R_OPTION_HTTP_1_0_SERVER ( * Allow to set several 'Content-Length' headers. These headers will be used even with replies without body. * @param val the value of the parameter * @return structure with the requested setting */ -static MHD_INLINE struct MHD_responseOptionAndValue +static MHD_INLINE struct MHD_ResponseOptionAndValue MHD_R_OPTION_INSANITY_HEADER_CONTENT_LENGTH ( enum MHD_Bool val ) @@ -481,7 +481,7 @@ MHD_R_OPTION_INSANITY_HEADER_CONTENT_LENGTH ( * @param term_cb_cls the closure for the callback * @return structure with the requested setting */ -static MHD_INLINE struct MHD_responseOptionAndValue +static MHD_INLINE struct MHD_ResponseOptionAndValue MHD_R_OPTION_TERMINATION_CALLBACK ( MHD_RequestTerminationCallback term_cb, void *term_cb_cls diff --git a/src/include/options-generator.c b/src/include/options-generator.c index f8bc3a0e..56459427 100644 --- a/src/include/options-generator.c +++ b/src/include/options-generator.c @@ -1019,13 +1019,23 @@ TOP: " * @author %s-options-generator.c\n" " */\n" "\n" - "#include \"mhd_sys_options.h\"\n" + "#include \"sys_bool_type.h\"\n" "#include \"sys_base_types.h\"\n" "#include \"sys_malloc.h\"\n" "#include \n" "#include \"mhd_%s.h\"\n" "#include \"%s_options.h\"\n" - "#include \"mhd_public_api.h\"\n" + "#include \"mhd_public_api.h\"\n", + category, + category, + category, + category); + if (0 == strcmp (category, "response")) + fprintf (f, + "#include \"mhd_locks.h\"\n" + "#include \"mhd_assert.h\"\n" + "#include \"response_funcs.h\"\n"); + fprintf (f, "\n" "MHD_FN_PAR_NONNULL_ALL_ MHD_EXTERN_\n" "enum MHD_StatusCode\n" @@ -1035,29 +1045,43 @@ TOP: " size_t options_max_num)\n" "{\n", category, - category, - category, - category, - category, capitalize (category), category, capitalize (category)); fprintf (f, - " struct %sOptions *const settings = %s->settings;\n" - " size_t i;\n" - "\n", + " struct %sOptions *restrict settings = %s->settings;\n" + " enum MHD_StatusCode res = MHD_SC_OK;\n" + " size_t i;\n", capitalize (category), category); if (0 == strcmp (category, "daemon")) { fprintf (f, + "\n" " if (mhd_DAEMON_STATE_NOT_STARTED != daemon->state)\n" " return MHD_SC_TOO_LATE;\n" "\n"); } + else if (0 == strcmp (category, "response")) + { + fprintf (f, + " bool need_unlock = false;\n" + "\n" + " if (response->frozen)\n" + " return MHD_SC_TOO_LATE;\n" + " if (response->reuse.reusable)\n" + " {\n" + " need_unlock = true;\n" + " if (! mhd_mutex_lock(&response->reuse.settings_lock))\n" + " return MHD_SC_RESPONSE_MUTEX_LOCK_FAILED;\n" + " mhd_assert (1 == mhd_atomic_counter_get(&response->reuse.counter));\n" + " }\n" + "\n"); + } else { fprintf (f, + "\n" " if (NULL == settings)\n" " return MHD_SC_TOO_LATE;\n" "\n"); @@ -1065,29 +1089,39 @@ TOP: fprintf (f, " for (i = 0; i < options_max_num; i++)\n" " {\n" - " const struct MHD_%sOptionAndValue *const option = options + i;\n" + " const struct MHD_%sOptionAndValue *const option\n" + " = options + i;\n" " switch (option->opt)\n" " {\n", capitalize (category)); fprintf (f, " case MHD_%c_O_END:\n" - " return MHD_SC_OK;\n", + " i = options_max_num - 1;\n" + " break;\n", (char) toupper (*category)); iterate (head, &dump_option_set_switch); fprintf (f, " case MHD_%c_O_SENTINEL:\n" " default: /* for -Wswitch-default -Wswitch-enum */ \n" + " res = MHD_SC_OPTION_UNKNOWN;\n" + " i = options_max_num - 1;\n" " break;\n", (char) toupper (*category)); fprintf (f, " }\n" - " return MHD_SC_OPTION_UNKNOWN;\n" - " }\n" - " return MHD_SC_OK;\n"); + " }\n"); + if (0 == strcmp (category, "response")) + { + fprintf (f, + "\n" + " if (need_unlock)\n" + " mhd_mutex_lock_chk(&response->reuse.settings_lock);\n" + "\n"); + } fprintf (f, + " return res;\n" "}\n"); - fclose (f); chmod (so_c, S_IRUSR | S_IRGRP | S_IROTH); free (so_c); @@ -1122,7 +1156,8 @@ TOP: "#include \"mhd_sys_options.h\"\n" "#include \"mhd_public_api.h\"\n" "\n" - "struct %sOptions {\n", + "struct %sOptions\n" + "{\n", category, category, uppercase (category), @@ -1133,7 +1168,7 @@ TOP: fprintf (f, "};\n" "\n" - "#endif /* ! MHD_%s_OPTIONS_H */\n", + "#endif /* ! MHD_%s_OPTIONS_H 1 */\n", uppercase (category)); fclose (f); chmod (do_h, S_IRUSR | S_IRGRP | S_IROTH); diff --git a/src/include/r_options.rec b/src/include/r_options.rec index af46efc9..9cb1866c 100644 --- a/src/include/r_options.rec +++ b/src/include/r_options.rec @@ -20,7 +20,7 @@ Name: REUSABLE Value: 20 Type: enum MHD_Bool -Comment: Make the response object re-usable. +Comment: Make the response object re-usable. (FIXME: not used in struct ResponseOptions; remove!?) + The response will not be consumed by MHD_action_from_response() and must be destroyed by MHD_response_destroy(). + Useful if the same response is often used to reply. diff --git a/src/mhd2/daemon_options.h b/src/mhd2/daemon_options.h index 6d5deec4..aef89fa4 100644 --- a/src/mhd2/daemon_options.h +++ b/src/mhd2/daemon_options.h @@ -12,7 +12,8 @@ #include "mhd_sys_options.h" #include "mhd_public_api.h" -struct DaemonOptions { +struct DaemonOptions +{ /** * Value for #MHD_D_O_WORK_MODE. * the object created by one of the next functions/macros: #MHD_WM_OPTION_EXTERNAL_PERIODIC(), #MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_LEVEL(), #MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_EDGE(), #MHD_WM_OPTION_EXTERNAL_SINGLE_FD_WATCH(), #MHD_WM_OPTION_WORKER_THREADS(), #MHD_WM_OPTION_THREAD_PER_CONNECTION() @@ -286,4 +287,4 @@ struct DaemonOptions { }; -#endif /* ! MHD_DAEMON_OPTIONS_H */ +#endif /* ! MHD_DAEMON_OPTIONS_H 1 */ diff --git a/src/mhd2/daemon_set_options.c b/src/mhd2/daemon_set_options.c index dcd0375f..d3a148c0 100644 --- a/src/mhd2/daemon_set_options.c +++ b/src/mhd2/daemon_set_options.c @@ -6,7 +6,7 @@ * @author daemon-options-generator.c */ -#include "mhd_sys_options.h" +#include "sys_bool_type.h" #include "sys_base_types.h" #include "sys_malloc.h" #include @@ -21,7 +21,8 @@ MHD_daemon_set_options ( const struct MHD_DaemonOptionAndValue *options, size_t options_max_num) { - struct DaemonOptions *const settings = daemon->settings; + struct DaemonOptions *restrict settings = daemon->settings; + enum MHD_StatusCode res = MHD_SC_OK; size_t i; if (mhd_DAEMON_STATE_NOT_STARTED != daemon->state) @@ -29,11 +30,13 @@ MHD_daemon_set_options ( for (i = 0; i < options_max_num; i++) { - const struct MHD_DaemonOptionAndValue *const option = options + i; + const struct MHD_DaemonOptionAndValue *const option + = options + i; switch (option->opt) { case MHD_D_O_END: - return MHD_SC_OK; + i = options_max_num - 1; + break; case MHD_D_O_WORK_MODE: settings->work_mode = option->val.work_mode; continue; @@ -50,20 +53,18 @@ MHD_daemon_set_options ( continue; case MHD_D_O_BIND_SA: /* custom setter */ - if (0 != option->val.bind_sa.v_sa_len) - { - if (NULL != settings->bind_sa.v_sa) - free (settings->bind_sa.v_sa); - - settings->bind_sa.v_sa = malloc (option->val.bind_sa.v_sa_len); - if (NULL == settings->bind_sa.v_sa) - return MHD_SC_DAEMON_MALLOC_FAILURE; - - memcpy (settings->bind_sa.v_sa, option->val.bind_sa.v_sa, - option->val.bind_sa.v_sa_len); - settings->bind_sa.v_sa_len = option->val.bind_sa.v_sa_len; - settings->bind_sa.v_dual = option->val.bind_sa.v_dual; - } + if (0 != option->val.bind_sa.v_sa_len) + { + if (NULL != settings->bind_sa.v_sa) + free (settings->bind_sa.v_sa); + settings->bind_sa.v_sa = malloc (option->val.bind_sa.v_sa_len); + if (NULL == settings->bind_sa.v_sa) + return MHD_SC_DAEMON_MALLOC_FAILURE; + memcpy (settings->bind_sa.v_sa, option->val.bind_sa.v_sa, + option->val.bind_sa.v_sa_len); + settings->bind_sa.v_sa_len = option->val.bind_sa.v_sa_len; + settings->bind_sa.v_dual = option->val.bind_sa.v_dual; + } continue; case MHD_D_O_LISTEN_SOCKET: settings->listen_socket = option->val.listen_socket; @@ -167,23 +168,21 @@ MHD_daemon_set_options ( continue; case MHD_D_O_RANDOM_ENTROPY: /* custom setter */ - /* The is not an easy for automatic generations */ - if (0 != option->val.random_entropy.v_buf_size) - { - if (NULL != settings->random_entropy.v_buf) - free (settings->random_entropy.v_buf); - - settings->random_entropy.v_buf = - malloc (option->val.random_entropy.v_buf_size); - if (NULL == settings->random_entropy.v_buf) - return MHD_SC_DAEMON_MALLOC_FAILURE; - - memcpy (settings->random_entropy.v_buf, - option->val.random_entropy.v_buf, - option->val.random_entropy.v_buf_size); - settings->random_entropy.v_buf_size = - option->val.random_entropy.v_buf_size; - } + /* The is not an easy for automatic generations */ + if (0 != option->val.random_entropy.v_buf_size) + { + if (NULL != settings->random_entropy.v_buf) + free (settings->random_entropy.v_buf); + settings->random_entropy.v_buf = + malloc (option->val.random_entropy.v_buf_size); + if (NULL == settings->random_entropy.v_buf) + return MHD_SC_DAEMON_MALLOC_FAILURE; + memcpy (settings->random_entropy.v_buf, + option->val.random_entropy.v_buf, + option->val.random_entropy.v_buf_size); + settings->random_entropy.v_buf_size = + option->val.random_entropy.v_buf_size; + } continue; case MHD_D_O_DAUTH_MAP_SIZE: settings->dauth_map_size = option->val.dauth_map_size; @@ -199,9 +198,10 @@ MHD_daemon_set_options ( continue; case MHD_D_O_SENTINEL: default: /* for -Wswitch-default -Wswitch-enum */ + res = MHD_SC_OPTION_UNKNOWN; + i = options_max_num - 1; break; } - return MHD_SC_OPTION_UNKNOWN; } - return MHD_SC_OK; + return res; } diff --git a/src/mhd2/response_options.h b/src/mhd2/response_options.h index 85120146..ea9de6b2 100644 --- a/src/mhd2/response_options.h +++ b/src/mhd2/response_options.h @@ -6,22 +6,18 @@ * @author response-options-generator.c */ -/* EDITED MANUALLY */ - #ifndef MHD_RESPONSE_OPTIONS_H #define MHD_RESPONSE_OPTIONS_H 1 #include "mhd_sys_options.h" - #include "mhd_public_api.h" - struct ResponseOptions { /** * Value for #MHD_R_O_REUSABLE. */ - enum MHD_Bool reusable; /* Not used in this struct. FIXME: remove? */ + enum MHD_Bool reusable; /** diff --git a/src/mhd2/response_set_options.c b/src/mhd2/response_set_options.c index ec4682ef..d12b3053 100644 --- a/src/mhd2/response_set_options.c +++ b/src/mhd2/response_set_options.c @@ -6,59 +6,50 @@ * @author response-options-generator.c */ -/* EDITED MANUALLY */ - - -#include "mhd_sys_options.h" -#include "response_set_options.h" -#include "sys_base_types.h" #include "sys_bool_type.h" -#include "response_options.h" +#include "sys_base_types.h" +#include "sys_malloc.h" +#include #include "mhd_response.h" +#include "response_options.h" #include "mhd_public_api.h" #include "mhd_locks.h" #include "mhd_assert.h" #include "response_funcs.h" -/** - * Internal version of the #MHD_response_set_options() - * Assuming that settings lock is held by the MHD_response_set_options() - * @param response the response to change - * @param options the options to use - * @param options_max_num the maximum number of @a options to use - * @return #MHD_SC_OK on success, error code otherwise - */ -static MHD_FN_PAR_NONNULL_ALL_ enum MHD_StatusCode -response_set_options_int ( - struct MHD_Response *restrict response, - const struct MHD_ResponseOptionAndValue *restrict options, +MHD_FN_PAR_NONNULL_ALL_ MHD_EXTERN_ +enum MHD_StatusCode +MHD_response_set_options ( + struct MHD_Response *response, + const struct MHD_ResponseOptionAndValue *options, size_t options_max_num) { - struct ResponseOptions *restrict settings; + struct ResponseOptions *restrict settings = response->settings; + enum MHD_StatusCode res = MHD_SC_OK; size_t i; + bool need_unlock = false; if (response->frozen) - return MHD_SC_TOO_LATE; /* Re-check under the lock (if any) */ - - settings = response->settings; + return MHD_SC_TOO_LATE; + if (response->reuse.reusable) + { + need_unlock = true; + if (! mhd_mutex_lock(&response->reuse.settings_lock)) + return MHD_SC_RESPONSE_MUTEX_LOCK_FAILED; + mhd_assert (1 == mhd_atomic_counter_get(&response->reuse.counter)); + } for (i = 0; i < options_max_num; i++) { - const struct MHD_ResponseOptionAndValue *const volatile option = - options + i; - + const struct MHD_ResponseOptionAndValue *const option + = options + i; switch (option->opt) { case MHD_R_O_END: - return MHD_SC_OK; + i = options_max_num - 1; + break; case MHD_R_O_REUSABLE: - if (response->reuse.reusable && !option->val.reusable) - return MHD_SC_RESPONSE_CANNOT_CLEAR_REUSE; - else if (response->reuse.reusable) - continue; /* This flag has been set before */ - else - if (! response_make_reusable(response)) - return MHD_SC_RESPONSE_MUTEX_INIT_FAILED; + settings->reusable = option->val.reusable; continue; case MHD_R_O_HEAD_ONLY_RESPONSE: settings->head_only_response = option->val.head_only_response; @@ -83,38 +74,15 @@ response_set_options_int ( settings->termination_callback.v_term_cb_cls = option->val.termination_callback.v_term_cb_cls; continue; case MHD_R_O_SENTINEL: - default: + default: /* for -Wswitch-default -Wswitch-enum */ + res = MHD_SC_OPTION_UNKNOWN; + i = options_max_num - 1; break; } - return MHD_SC_OPTION_UNKNOWN; } - return MHD_SC_OK; -} - -MHD_FN_PAR_NONNULL_ALL_ MHD_EXTERN_ enum MHD_StatusCode -MHD_response_set_options (struct MHD_Response *response, - const struct MHD_ResponseOptionAndValue *options, - size_t options_max_num) -{ - bool need_unlock; - enum MHD_StatusCode res; - - if (response->frozen) - return MHD_SC_TOO_LATE; - - need_unlock = false; - if (response->reuse.reusable) - { - need_unlock = true; - if (! mhd_mutex_lock(&(response->reuse.settings_lock))) - return MHD_SC_RESPONSE_MUTEX_LOCK_FAILED; - mhd_assert (1 == mhd_atomic_counter_get(&(response->reuse.counter))); - } - - res = response_set_options_int(response, options, options_max_num); if (need_unlock) - mhd_mutex_unlock_chk(&(response->reuse.settings_lock)); + mhd_mutex_lock_chk(&response->reuse.settings_lock); return res; }