From c5288d378ad258d2e8e8cb174be3b9f233a312eb Mon Sep 17 00:00:00 2001 From: Arjun Shankar Date: Wed, 17 Oct 2018 17:47:29 +0200 Subject: Remove unnecessary locking when reading iconv configuration [BZ #22062] In iconv/gconv_conf.c, __gconv_get_path unnecessarily obtains a lock when populating the array pointed to by __gconv_path_elem. The locking is not necessary because all calls to __gconv_read_conf (which in turn calls __gconv_get_path) are serialized using __libc_once. This patch: - removes all locking in __gconv_get_path; - replaces all explicitly serialized __gconv_read_conf calls with calls to __gconv_load_conf, a new wrapper that is serialized internally; - adds a new test, iconv/tst-iconv_mt.c, to exercise iconv initialization, usage, and cleanup in a multi-threaded program; - indents __gconv_get_path correctly, removing tab characters (which makes the patch look a little bigger than it really is). After removing the unnecessary locking, it was confirmed that the test case fails if the relevant __libc_once is removed. Additionally, four localedata and iconvdata tests also fail. This gives confidence that the testsuite sufficiently guards against some regressions relating to multi-threading with iconv. Tested on x86_64 and i686. --- iconv/gconv_db.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'iconv/gconv_db.c') diff --git a/iconv/gconv_db.c b/iconv/gconv_db.c index 66e095d..86acfc7 100644 --- a/iconv/gconv_db.c +++ b/iconv/gconv_db.c @@ -687,10 +687,6 @@ find_derivation (const char *toset, const char *toset_expand, } -/* Control of initialization. */ -__libc_once_define (static, once); - - static const char * do_lookup_alias (const char *name) { @@ -709,7 +705,7 @@ __gconv_compare_alias (const char *name1, const char *name2) int result; /* Ensure that the configuration data is read. */ - __libc_once (once, __gconv_read_conf); + __gconv_load_conf (); if (__gconv_compare_alias_cache (name1, name2, &result) != 0) result = strcmp (do_lookup_alias (name1) ?: name1, @@ -729,7 +725,7 @@ __gconv_find_transform (const char *toset, const char *fromset, int result; /* Ensure that the configuration data is read. */ - __libc_once (once, __gconv_read_conf); + __gconv_load_conf (); /* Acquire the lock. */ __libc_lock_lock (__gconv_lock); -- cgit v1.1