From 1806bfa04f3349de2a33c26a51f3c8c7724522eb Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Sun, 1 Jan 2023 23:29:11 +0200 Subject: [PATCH 4/4] 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 | 23 +++++++++++++---------- common/fc_interface.h | 6 +++--- server/srv_main.c | 14 ++++++++------ tools/civmanual.c | 6 +++--- tools/modinst.c | 9 +++++---- tools/ruledit/ruledit.cpp | 5 ++--- 7 files changed, 41 insertions(+), 35 deletions(-) diff --git a/client/client_main.c b/client/client_main.c index a12448520a..653983616a 100644 --- a/client/client_main.c +++ b/client/client_main.c @@ -339,10 +339,13 @@ int client_main(int argc, char *argv[]) # endif /* FREECIV_NDEBUG */ #endif /* WIN32_NATIVE */ - 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 @@ -354,7 +357,6 @@ int client_main(int argc, char *argv[]) init_ai(ai); } - init_nls(); #ifdef ENABLE_NLS (void) bindtextdomain("freeciv-nations", get_locale_dir()); #endif @@ -739,8 +741,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(); @@ -1370,7 +1371,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 6dcb5eb214..c39db40ecc 100644 --- a/common/fc_interface.c +++ b/common/fc_interface.c @@ -48,28 +48,31 @@ 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->player_tile_vision_get); - fc_assert_exit(fc_funcs->gui_color_free); + /* Test the existence of each required function here! */ + fc_assert_exit(fc_funcs->player_tile_vision_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(); diff --git a/common/fc_interface.h b/common/fc_interface.h index 31b19706d4..03d4348498 100644 --- a/common/fc_interface.h +++ b/common/fc_interface.h @@ -44,11 +44,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 ce0a5020f2..536483c8ad 100644 --- a/server/srv_main.c +++ b/server/srv_main.c @@ -217,10 +217,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 @@ -1789,10 +1792,10 @@ 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(); + exit(EXIT_SUCCESS); } @@ -3348,7 +3351,6 @@ void server_game_free(void) **************************************************************************/ void srv_main(void) { - fc_interface_init_server(); advisors_init(); srv_prepare(); @@ -3431,7 +3433,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 5bd6e4245e..191a92779d 100644 --- a/tools/civmanual.c +++ b/tools/civmanual.c @@ -596,7 +596,8 @@ int main(int argc, char **argv) char *option = NULL; int retval = EXIT_SUCCESS; - init_nls(); + libfreeciv_init(FALSE); + registry_module_init(); init_character_encodings(FC_DEFAULT_DATA_ENCODING, FALSE); @@ -720,8 +721,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 f8d870e24c..84e3650cab 100644 --- a/tools/ruledit/ruledit.cpp +++ b/tools/ruledit/ruledit.cpp @@ -68,7 +68,7 @@ int main(int argc, char **argv) # endif /* FREECIV_NDEBUG */ #endif /* WIN32_NATIVE */ - init_nls(); + libfreeciv_init(FALSE); #ifdef ENABLE_NLS (void) bindtextdomain("freeciv-ruledit", get_locale_dir()); @@ -104,8 +104,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(); -- 2.39.0