From 07ba52e5c264dac6922092a080a26d8043cb23b6 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Sun, 1 Jan 2023 23:12:17 +0200 Subject: [PATCH 29/29] 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 programs 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 | 9 ++++---- tools/ruledit/ruledit.cpp | 13 ++++++----- tools/ruleup.c | 14 ++++++------ tools/shared/tools_fc_interface.c | 2 +- 9 files changed, 67 insertions(+), 58 deletions(-) diff --git a/client/client_main.c b/client/client_main.c index b1cd561d52..049b10c14e 100644 --- a/client/client_main.c +++ b/client/client_main.c @@ -363,10 +363,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 @@ -378,7 +381,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 @@ -755,8 +757,7 @@ void client_exit(int return_value) conn_list_destroy(game.est_connections); registry_module_close(); - free_libfreeciv(); - free_nls(); + libfreeciv_free(); backtrace_deinit(); log_close(); @@ -1525,7 +1526,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 86c196753a..9e21bf9fbd 100644 --- a/server/srv_main.c +++ b/server/srv_main.c @@ -223,10 +223,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 @@ -1850,11 +1853,11 @@ void 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); } @@ -3429,8 +3432,6 @@ void server_game_free(void) **************************************************************************/ void srv_main(void) { - fc_interface_init_server(); - srv_prepare(); /* Run server loop */ @@ -3624,7 +3625,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 5c3545108d..f97587f262 100644 --- a/tools/civmanual.c +++ b/tools/civmanual.c @@ -775,7 +775,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); @@ -838,10 +844,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); @@ -905,8 +907,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..e9268a262c 100644 --- a/tools/fcmp/modinst.c +++ b/tools/fcmp/modinst.c @@ -81,13 +81,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 +102,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 f29e64ba7d..b3b14c05d6 100644 --- a/tools/ruledit/ruledit.cpp +++ b/tools/ruledit/ruledit.cpp @@ -77,7 +77,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()); @@ -106,10 +110,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); @@ -126,8 +128,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