From 7c69792293acbbccd2bf271268f0d7852be4c4ab Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Sun, 1 Jan 2023 23:19:34 +0200 Subject: [PATCH 15/15] 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 | 14 +++++++----- tools/civmanual.c | 15 ++++++------ tools/modinst.c | 9 ++++---- tools/ruledit/ruledit.cpp | 13 ++++++----- tools/ruleup.c | 14 ++++++------ tools/shared/tools_fc_interface.c | 2 +- 9 files changed, 67 insertions(+), 57 deletions(-) diff --git a/client/client_main.c b/client/client_main.c index 792b0e34d0..57f0e69f1a 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(); @@ -1526,7 +1527,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 4bee314345..3819e26bf4 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 8e09e39ab0..d74ab9beba 100644 --- a/server/srv_main.c +++ b/server/srv_main.c @@ -220,10 +220,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 @@ -1803,11 +1806,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); } @@ -3377,7 +3380,6 @@ void server_game_free(void) **************************************************************************/ void srv_main(void) { - fc_interface_init_server(); advisors_init(); srv_prepare(); @@ -3543,7 +3545,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 a25b3ddd57..6e83627d69 100644 --- a/tools/civmanual.c +++ b/tools/civmanual.c @@ -689,7 +689,13 @@ int main(int argc, char **argv) char *option = NULL; int retval = EXIT_SUCCESS; - 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); @@ -750,10 +756,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); @@ -815,8 +817,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/modinst.c b/tools/modinst.c index 8dc444ad50..bc0a339533 100644 --- a/tools/modinst.c +++ b/tools/modinst.c @@ -181,13 +181,15 @@ const char *get_installed_version(const char *name, enum modpack_type type) **************************************************************************/ 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)); } /************************************************************************** @@ -200,6 +202,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 7732b5ac40..bd3b2f5bc0 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()); @@ -105,10 +109,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); @@ -121,8 +123,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 30f05184f4..cee2e22c7d 100644 --- a/tools/ruleup.c +++ b/tools/ruleup.c @@ -148,13 +148,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(); @@ -164,9 +168,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; @@ -201,8 +202,7 @@ int main(int argc, char **argv) registry_module_close(); log_close(); - free_libfreeciv(); - free_nls(); + libfreeciv_free(); cmdline_option_values_free(); return EXIT_SUCCESS; diff --git a/tools/shared/tools_fc_interface.c b/tools/shared/tools_fc_interface.c index b93b1d73a9..f99acbc038 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