[PATCH libX11 3/3] Make conv_list thread safe.
Jacek Caban
jacek at codeweavers.com
Thu Aug 10 21:05:12 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