[PATCH libX11 3/3] Make conv_list thread safe.

Jacek Caban jacek at codeweavers.com
Mon Aug 14 17:20:20 UTC 2017


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>
---
 src/locking.c         | 13 +++++++++++++
 src/xlibi18n/lcConv.c | 25 ++++++++++++++++++++-----
 2 files changed, 33 insertions(+), 5 deletions(-)

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



More information about the xorg-devel mailing list