From 0f71d0347e575aec9230b71407bc9e0beb5f513d Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Sun, 1 Jan 2023 22:40:30 +0200 Subject: [PATCH 41/41] Initialize mutexes of the low level fallback functions earlier Make sure fallback fc_vsnprintf() mutex is initialized before it's needed, and not freed as long as it's needed. - fc_interface_init() renamed as libfreeciv_init() - free_libfreeciv() renamed as libfreeciv_free() - libfreeciv_init() takes a parameter telling if fc_interface check should be done, so programs without fc_interface can use it - libfreciv_init() call added to modpack installer - In other prograns libfreeciv_init() call moved earlier, as needed - init_nls() / free_nls() calls moved inside libfreeciv_init() / libfreeciv_free() to have them exactly right time See osdn #46418 Signed-off-by: Marko Lindqvist --- client/client_main.c | 13 ++++++----- common/fc_interface.c | 38 +++++++++++++++++-------------- common/fc_interface.h | 6 ++--- server/srv_main.c | 15 ++++++------ tools/civmanual.c | 15 ++++++------ tools/fcmp/modinst.c | 12 ++++++---- tools/ruledit/ruledit.cpp | 13 ++++++----- tools/ruleup.c | 14 ++++++------ tools/shared/tools_fc_interface.c | 2 +- 9 files changed, 70 insertions(+), 58 deletions(-) diff --git a/client/client_main.c b/client/client_main.c index 2668ab74cd..95f3bda671 100644 --- a/client/client_main.c +++ b/client/client_main.c @@ -364,10 +364,13 @@ int client_main(int argc, char *argv[], bool postpone_tileset) # endif /* FREECIV_NDEBUG */ #endif /* FREECIV_MSWINDOWS */ - i_am_client(); /* Tell to libfreeciv that we are client */ - + /* fc_interface_init_client() includes low level support like + * guaranteeing that fc_vsnprintf() will work after it, + * so this need to be early. */ fc_interface_init_client(); + i_am_client(); /* Tell to libfreeciv that we are client */ + game.client.ruleset_init = FALSE; /* Ensure that all AIs are initialized to unused state @@ -379,7 +382,6 @@ int client_main(int argc, char *argv[], bool postpone_tileset) init_ai(ai); } - init_nls(); #ifdef ENABLE_NLS (void) bindtextdomain("freeciv-nations", get_locale_dir()); #endif @@ -746,8 +748,7 @@ void fc__noreturn client_exit(int return_value) free_svg_flag_API(); registry_module_close(); - free_libfreeciv(); - free_nls(); + libfreeciv_free(); backtrace_deinit(); log_close(); @@ -1518,7 +1519,7 @@ static void fc_interface_init_client(void) /* Keep this function call at the end. It checks if all required functions are defined. */ - fc_interface_init(); + libfreeciv_init(TRUE); } /**********************************************************************//** diff --git a/common/fc_interface.c b/common/fc_interface.c index 9365a79242..5e49ca5ce2 100644 --- a/common/fc_interface.c +++ b/common/fc_interface.c @@ -50,35 +50,38 @@ struct functions *fc_interface_funcs(void) } /************************************************************************//** - Test and initialize the functions. The existence of all functions should - be checked! + Initialize libfreeciv. + With check_fc_interface, also tests and initialize the functions. ****************************************************************************/ -void fc_interface_init(void) +void libfreeciv_init(bool check_fc_interface) { fc_support_init(); + init_nls(); - fc_funcs = &fc_functions; + if (check_fc_interface) { + fc_funcs = &fc_functions; - /* Test the existence of each required function here! */ - fc_assert_exit(fc_funcs->server_setting_by_name); - fc_assert_exit(fc_funcs->server_setting_name_get); - fc_assert_exit(fc_funcs->server_setting_type_get); - fc_assert_exit(fc_funcs->server_setting_val_bool_get); - fc_assert_exit(fc_funcs->server_setting_val_int_get); - fc_assert_exit(fc_funcs->server_setting_val_bitwise_get); - fc_assert_exit(fc_funcs->player_tile_vision_get); - fc_assert_exit(fc_funcs->player_tile_city_id_get); - fc_assert_exit(fc_funcs->gui_color_free); + /* Test the existence of each required function here! */ + fc_assert_exit(fc_funcs->server_setting_by_name); + fc_assert_exit(fc_funcs->server_setting_name_get); + fc_assert_exit(fc_funcs->server_setting_type_get); + fc_assert_exit(fc_funcs->server_setting_val_bool_get); + fc_assert_exit(fc_funcs->server_setting_val_int_get); + fc_assert_exit(fc_funcs->server_setting_val_bitwise_get); + fc_assert_exit(fc_funcs->player_tile_vision_get); + fc_assert_exit(fc_funcs->player_tile_city_id_get); + fc_assert_exit(fc_funcs->gui_color_free); - fc_funcs_defined = TRUE; + fc_funcs_defined = TRUE; - setup_real_activities_array(); + setup_real_activities_array(); + } } /************************************************************************//** Free misc resources allocated for libfreeciv. ****************************************************************************/ -void free_libfreeciv(void) +void libfreeciv_free(void) { diplrel_mess_close(); free_data_dir_names(); @@ -87,5 +90,6 @@ void free_libfreeciv(void) free_user_home_dir(); free_fileinfo_data(); netfile_free(); + free_nls(); fc_support_free(); } diff --git a/common/fc_interface.h b/common/fc_interface.h index 649a0dfd65..3546c0bc97 100644 --- a/common/fc_interface.h +++ b/common/fc_interface.h @@ -56,11 +56,11 @@ struct functions { extern const struct functions *fc_funcs; struct functions *fc_interface_funcs(void); -void fc_interface_init(void); -void free_libfreeciv(void); +void libfreeciv_init(bool check_fc_interface); +void libfreeciv_free(void); #ifdef __cplusplus } #endif /* __cplusplus */ -#endif /* FC__FC_INTERFACE_H */ +#endif /* FC__FC_INTERFACE_H */ diff --git a/server/srv_main.c b/server/srv_main.c index d0e8e1226e..1d0a06e954 100644 --- a/server/srv_main.c +++ b/server/srv_main.c @@ -224,10 +224,13 @@ void init_game_seed(void) **************************************************************************/ void srv_init(void) { + /* fc_interface_init_server() includes low level support like + * guaranteeing that fc_vsnprintf() will work after it, + * so this need to be early. */ + fc_interface_init_server(); + i_am_server(); /* Tell to libfreeciv that we are server */ - /* NLS init */ - init_nls(); #ifdef ENABLE_NLS (void) bindtextdomain("freeciv-nations", get_locale_dir()); #endif @@ -1910,11 +1913,11 @@ void fc__noreturn server_quit(void) timing_log_free(); registry_module_close(); fc_destroy_mutex(&game.server.mutexes.city_list); - free_libfreeciv(); - free_nls(); + libfreeciv_free(); con_log_close(); cmdline_option_values_free(); readline_atexit(); + exit(EXIT_SUCCESS); } @@ -3492,8 +3495,6 @@ void server_game_free(void) **************************************************************************/ void fc__noreturn srv_main(void) { - fc_interface_init_server(); - srv_prepare(); /* Run server loop */ @@ -3688,7 +3689,7 @@ static void fc_interface_init_server(void) /* Keep this function call at the end. It checks if all required functions are defined. */ - fc_interface_init(); + libfreeciv_init(TRUE); } /**********************************************************************//** diff --git a/tools/civmanual.c b/tools/civmanual.c index e988d011b4..dac8fa806d 100644 --- a/tools/civmanual.c +++ b/tools/civmanual.c @@ -777,7 +777,13 @@ int main(int argc, char **argv) int retval = EXIT_SUCCESS; struct tag_types *tag_info = &html_tags; - init_nls(); + /* Initialize the fc_interface functions needed to generate the help + * text. + * fc_interface_init_tool() includes low level support like + * guaranteeing that fc_vsnprintf() will work after it, + * so this need to be early. */ + fc_interface_init_tool(); + registry_module_init(); init_character_encodings(FC_DEFAULT_DATA_ENCODING, FALSE); @@ -840,10 +846,6 @@ int main(int argc, char **argv) /* Get common code to treat us as a tool. */ i_am_tool(); - /* Initialize the fc_interface functions needed to generate the help - * text. */ - fc_interface_init_tool(); - /* Initialize game with default values */ game_init(FALSE); @@ -907,8 +909,7 @@ int main(int argc, char **argv) con_log_close(); registry_module_close(); - free_libfreeciv(); - free_nls(); + libfreeciv_free(); cmdline_option_values_free(); return retval; diff --git a/tools/fcmp/modinst.c b/tools/fcmp/modinst.c index 42c844cc77..2c719a698f 100644 --- a/tools/fcmp/modinst.c +++ b/tools/fcmp/modinst.c @@ -30,6 +30,9 @@ /* common */ #include "fc_interface.h" +/* tools */ +#include "tools_fc_interface.h" + /* modinst */ #include "mpdb.h" @@ -81,13 +84,15 @@ void load_install_info_lists(struct fcmp_params *fcmp) **************************************************************************/ void fcmp_init(void) { - init_nls(); + libfreeciv_init(FALSE); + init_character_encodings(FC_DEFAULT_DATA_ENCODING, FALSE); registry_module_init(); fc_init_network(); - fc_srand(time(NULL)); /* Needed at least for Windows version of netfile_get_section_file() */ + /* Needed at least for Windows version of netfile_get_section_file() */ + fc_srand(time(NULL)); } /**********************************************************************//** @@ -100,6 +105,5 @@ void fcmp_deinit(void) /* log_init() was not done by fcmp_init(); we assume the caller called * fcmp_parse_cmdline() (which sets up logging) in between */ log_close(); - free_libfreeciv(); - free_nls(); + libfreeciv_free(); } diff --git a/tools/ruledit/ruledit.cpp b/tools/ruledit/ruledit.cpp index 28b6da1619..e43f7f4c0c 100644 --- a/tools/ruledit/ruledit.cpp +++ b/tools/ruledit/ruledit.cpp @@ -76,7 +76,11 @@ int main(int argc, char **argv) # endif // FREECIV_NDEBUG #endif // FREECIV_MSWINDOWS - init_nls(); + /* Initialize the fc_interface functions needed to understand rules. + * fc_interface_init_tool() includes low level support like + * guaranteeing that fc_vsnprintf() will work after it, + * so this need to be early. */ + fc_interface_init_tool(); #ifdef ENABLE_NLS (void) bindtextdomain("freeciv-ruledit", get_locale_dir()); @@ -103,10 +107,8 @@ int main(int argc, char **argv) game.info.aifill = 0; game_init(FALSE); - i_am_tool(); - // Initialize the fc_interface functions needed to understand rules. - fc_interface_init_tool(); + i_am_tool(); if (comments_load()) { ruledit_qt_run(ui_options, argv); @@ -123,8 +125,7 @@ int main(int argc, char **argv) registry_module_close(); log_close(); - free_libfreeciv(); - free_nls(); + libfreeciv_free(); // Clean up command line arguments. cmdline_option_values_free(); diff --git a/tools/ruleup.c b/tools/ruleup.c index 852f9f66d1..aa1bcd7843 100644 --- a/tools/ruleup.c +++ b/tools/ruleup.c @@ -154,13 +154,17 @@ int main(int argc, char **argv) # endif /* FREECIV_NDEBUG */ #endif /* FREECIV_MSWINDOWS */ - init_nls(); + /* Initialize the fc_interface functions needed to understand rules. + * fc_interface_init_tool() includes low level support like + * guaranteeing that fc_vsnprintf() will work after it, + * so this need to be early. */ + fc_interface_init_tool(); registry_module_init(); init_character_encodings(FC_DEFAULT_DATA_ENCODING, FALSE); rup_parse_cmdline(argc, argv); - + log_init(NULL, loglevel, NULL, NULL, fatal_assertions); init_connections(); @@ -170,9 +174,6 @@ int main(int argc, char **argv) game_init(FALSE); i_am_tool(); - /* Initialize the fc_interface functions needed to understand rules. */ - fc_interface_init_tool(); - /* Set ruleset user requested to use */ if (rs_selected == NULL) { rs_selected = GAME_DEFAULT_RULESETDIR; @@ -234,8 +235,7 @@ int main(int argc, char **argv) registry_module_close(); log_close(); - free_libfreeciv(); - free_nls(); + libfreeciv_free(); cmdline_option_values_free(); return exit_status; diff --git a/tools/shared/tools_fc_interface.c b/tools/shared/tools_fc_interface.c index 07c1275220..a90444ea4c 100644 --- a/tools/shared/tools_fc_interface.c +++ b/tools/shared/tools_fc_interface.c @@ -76,5 +76,5 @@ void fc_interface_init_tool(void) /* Keep this function call at the end. It checks if all required functions are defined. */ - fc_interface_init(); + libfreeciv_init(TRUE); } -- 2.39.0