summarylogtreecommitdiffstats
path: root/threadsafe.patch
diff options
context:
space:
mode:
Diffstat (limited to 'threadsafe.patch')
-rw-r--r--threadsafe.patch180
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
+