diff options
Diffstat (limited to 'threadsafe.patch')
-rw-r--r-- | threadsafe.patch | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/threadsafe.patch b/threadsafe.patch new file mode 100644 index 000000000000..0bb2e7354610 --- /dev/null +++ b/threadsafe.patch @@ -0,0 +1,180 @@ +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 <jacek at codeweavers.com> +--- +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 <stdio.h> ++#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 + |