From the Xorg mailing list: https://lists.x.org/archives/xorg-devel/2017-August/054347.html Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=55678 Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=68538 Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=69088 Signed-off-by: Jacek Caban --- diff --git a/src/xlibi18n/lcWrap.c b/src/xlibi18n/lcWrap.c index 38242608..43b4d622 100644 --- a/src/xlibi18n/lcWrap.c +++ b/src/xlibi18n/lcWrap.c @@ -324,6 +324,8 @@ _XCloseLC( { XLCdList cur, *prev; + _XLockMutex(_Xi18n_lock); + for (prev = &lcd_list; (cur = *prev); prev = &cur->next) { if (cur->lcd == lcd) { if (--cur->ref_count < 1) { @@ -339,6 +341,8 @@ _XCloseLC( _XlcDeInitLoader(); loader_list = NULL; } + + _XUnlockMutex(_Xi18n_lock); } /* -- 2.13.0 diff --git a/src/xlibi18n/lcWrap.c b/src/xlibi18n/lcWrap.c index 43b4d622..5339dcf3 100644 --- a/src/xlibi18n/lcWrap.c +++ b/src/xlibi18n/lcWrap.c @@ -352,17 +352,7 @@ _XCloseLC( XLCd _XlcCurrentLC(void) { - XLCd lcd; - static XLCd last_lcd = NULL; - - lcd = _XOpenLC((char *) NULL); - - if (last_lcd) - _XCloseLC(last_lcd); - - last_lcd = lcd; - - return lcd; + return _XOpenLC(NULL); } XrmMethods diff --git a/src/locking.c b/src/locking.c index 9f4fe067..3981c0f5 100644 --- a/src/locking.c +++ b/src/locking.c @@ -66,6 +66,8 @@ in this Software without prior written authorization from The Open Group. /* in lcWrap.c */ extern LockInfoPtr _Xi18n_lock; +/* in lcConv.c */ +extern LockInfoPtr _conv_lock; #ifdef WIN32 static DWORD _X_TlsIndex = (DWORD)-1; @@ -98,6 +100,7 @@ static xthread_t _Xthread_self(void) static LockInfoRec global_lock; static LockInfoRec i18n_lock; +static LockInfoRec conv_lock; static void _XLockMutex( LockInfoPtr lip @@ -594,12 +597,22 @@ Status XInitThreads(void) global_lock.lock = NULL; return 0; } + if (!(conv_lock.lock = xmutex_malloc())) { + xmutex_free(global_lock.lock); + global_lock.lock = NULL; + xmutex_free(i18n_lock.lock); + i18n_lock.lock = NULL; + return 0; + } _Xglobal_lock = &global_lock; xmutex_init(_Xglobal_lock->lock); xmutex_set_name(_Xglobal_lock->lock, "Xlib global"); _Xi18n_lock = &i18n_lock; xmutex_init(_Xi18n_lock->lock); xmutex_set_name(_Xi18n_lock->lock, "Xlib i18n"); + _conv_lock = &conv_lock; + xmutex_init(_conv_lock->lock); + xmutex_set_name(_conv_lock->lock, "Xlib conv"); _XLockMutex_fn = _XLockMutex; _XUnlockMutex_fn = _XUnlockMutex; _XCreateMutex_fn = _XCreateMutex; diff --git a/src/xlibi18n/lcConv.c b/src/xlibi18n/lcConv.c index 7d9a4738..32699746 100644 --- a/src/xlibi18n/lcConv.c +++ b/src/xlibi18n/lcConv.c @@ -29,6 +29,11 @@ #include "Xlibint.h" #include "XlcPubI.h" #include +#include "locking.h" + +#ifdef XTHREADS +LockInfoPtr _conv_lock; +#endif typedef struct _XlcConverterListRec { XLCd from_lcd; @@ -58,6 +63,9 @@ get_converter( XrmQuark to_type) { XlcConverterList list, prev = NULL; + XlcConv conv = NULL; + + _XLockMutex(_conv_lock); for (list = conv_list; list; list = list->next) { if (list->from_lcd == from_lcd && list->to_lcd == to_lcd @@ -69,13 +77,16 @@ get_converter( conv_list = list; } - return (*list->converter)(from_lcd, list->from, to_lcd, list->to); + conv = (*list->converter)(from_lcd, list->from, to_lcd, list->to); + break; } prev = list; } - return (XlcConv) NULL; + _XUnlockMutex(_conv_lock); + + return conv; } Bool @@ -92,18 +103,20 @@ _XlcSetConverter( from_type = XrmStringToQuark(from); to_type = XrmStringToQuark(to); + _XLockMutex(_conv_lock); + for (list = conv_list; list; list = list->next) { if (list->from_lcd == from_lcd && list->to_lcd == to_lcd && list->from_type == from_type && list->to_type == to_type) { list->converter = converter; - return True; + goto ret; } } list = Xmalloc(sizeof(XlcConverterListRec)); if (list == NULL) - return False; + goto ret; list->from_lcd = from_lcd; list->from = from; @@ -115,7 +128,9 @@ _XlcSetConverter( list->next = conv_list; conv_list = list; - return True; +ret: + _XUnlockMutex(_conv_lock); + return list != NULL; } typedef struct _ConvRec { -- 2.13.0